diff --git a/Windows_Libs/Dev/Input/Input.vcxproj b/Windows_Libs/Dev/Input/Input.vcxproj
index ad24d91..3188e2b 100644
--- a/Windows_Libs/Dev/Input/Input.vcxproj
+++ b/Windows_Libs/Dev/Input/Input.vcxproj
@@ -49,7 +49,7 @@
StaticLibrary
false
- v110
+ v145
true
Unicode
diff --git a/Windows_Libs/Dev/Input/Input.vcxproj.filters b/Windows_Libs/Dev/Input/Input.vcxproj.filters
index 644602f..53711b9 100644
--- a/Windows_Libs/Dev/Input/Input.vcxproj.filters
+++ b/Windows_Libs/Dev/Input/Input.vcxproj.filters
@@ -9,10 +9,6 @@
{93995380-89BD-4b04-88EB-625FBE52EBFB}
h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
diff --git a/Windows_Libs/Dev/Profile/Profile.vcxproj b/Windows_Libs/Dev/Profile/Profile.vcxproj
index 11e6d42..ec99799 100644
--- a/Windows_Libs/Dev/Profile/Profile.vcxproj
+++ b/Windows_Libs/Dev/Profile/Profile.vcxproj
@@ -49,7 +49,7 @@
StaticLibrary
false
- v110
+ v145
true
Unicode
diff --git a/Windows_Libs/Dev/Profile/Profile.vcxproj.filters b/Windows_Libs/Dev/Profile/Profile.vcxproj.filters
index 857584d..ddd612f 100644
--- a/Windows_Libs/Dev/Profile/Profile.vcxproj.filters
+++ b/Windows_Libs/Dev/Profile/Profile.vcxproj.filters
@@ -9,10 +9,6 @@
{93995380-89BD-4b04-88EB-625FBE52EBFB}
h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
diff --git a/Windows_Libs/Dev/Render/4J_Render.cpp b/Windows_Libs/Dev/Render/4J_Render.cpp
index 38fe1da..0695b09 100644
--- a/Windows_Libs/Dev/Render/4J_Render.cpp
+++ b/Windows_Libs/Dev/Render/4J_Render.cpp
@@ -6,7 +6,9 @@ C4JRender RenderManager;
void C4JRender::Tick()
{
+#if _DEBUG
InternalRenderManager.CBuffTick();
+#endif
}
void C4JRender::UpdateGamma(unsigned short usGamma)
diff --git a/Windows_Libs/Dev/Render/Profiler.h b/Windows_Libs/Dev/Render/Profiler.h
new file mode 100644
index 0000000..e78cd52
--- /dev/null
+++ b/Windows_Libs/Dev/Render/Profiler.h
@@ -0,0 +1,14 @@
+#pragma once
+
+// enable only if you know what you're doing
+// requires linking Minecraft.Client against Ws2_32.lib
+// stats are available at http://127.0.0.1:1338/
+
+//#define ENABLE_PROFILING
+
+#ifdef ENABLE_PROFILING
+#include "microprofile/microprofile.h"
+#define PROFILER_SCOPE(group, name, color) MICROPROFILE_SCOPEI(group, name, color);
+#else
+#define PROFILER_SCOPE(group, name, color) ((void)0);
+#endif
\ No newline at end of file
diff --git a/Windows_Libs/Dev/Render/Render.vcxproj b/Windows_Libs/Dev/Render/Render.vcxproj
index f0127eb..e7af720 100644
--- a/Windows_Libs/Dev/Render/Render.vcxproj
+++ b/Windows_Libs/Dev/Render/Render.vcxproj
@@ -49,7 +49,7 @@
StaticLibrary
false
- v110
+ v145
true
Unicode
@@ -123,7 +123,7 @@
true
stdafx.h
MultiThreadedDebug
- libpng\;zlib\;%(AdditionalIncludeDirectories)
+ libpng\;zlib\;microprofile\;%(AdditionalIncludeDirectories)
Default
true
@@ -148,7 +148,7 @@
true
stdafx.h
MultiThreaded
- libpng\;zlib\;%(AdditionalIncludeDirectories)
+ libpng\;zlib\;microprofile\;%(AdditionalIncludeDirectories)
@@ -167,6 +167,10 @@
+
+
+
+
@@ -329,6 +333,7 @@
+
diff --git a/Windows_Libs/Dev/Render/Render.vcxproj.filters b/Windows_Libs/Dev/Render/Render.vcxproj.filters
index 77d14ca..a54788a 100644
--- a/Windows_Libs/Dev/Render/Render.vcxproj.filters
+++ b/Windows_Libs/Dev/Render/Render.vcxproj.filters
@@ -9,9 +9,20 @@
{93995380-89BD-4b04-88EB-625FBE52EBFB}
h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+ {e5716c14-38f4-49f7-bf1a-916fbc7613a8}
+
+
+ {0681221a-1efa-43e4-b0f7-0b525172e486}
+
+
+ {0629c87a-576d-4163-8c60-dad190ee97d0}
+
+
+ {8be558c7-c6e6-4ef7-bfcb-83d29f079240}
+
+
+ {6cbd8b95-ff51-42d2-a66f-282d3a11c042}
@@ -21,33 +32,6 @@
Header Files
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
-
- Header Files
-
Header Files
@@ -87,6 +71,45 @@
Header Files
+
+ Header Files\zlib
+
+
+ Header Files\zlib
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\libpng
+
+
+ Header Files\microprofile
+
+
+ Header Files\microprofile
+
+
+ Header Files\microprofile
+
+
+ Header Files
+
@@ -114,52 +137,55 @@
Source Files
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
- Source Files
+ Source Files\libpng
+
+
+ Source Files\microprofile
\ No newline at end of file
diff --git a/Windows_Libs/Dev/Render/Renderer.h b/Windows_Libs/Dev/Render/Renderer.h
index 9f6ae23..24a4fc2 100644
--- a/Windows_Libs/Dev/Render/Renderer.h
+++ b/Windows_Libs/Dev/Render/Renderer.h
@@ -1,5 +1,6 @@
#pragma once
#include "4J_Render.h"
+#include "Profiler.h"
#include
#include
#include
@@ -13,6 +14,7 @@
#define STACK_TYPES 4
#define STACK_SIZE 16
#define MAX_MIP_LEVELS 5
+#define MAX_TEXTURES 512
#define NUM_COMMAND_HANDLES 0x800000
#define MAX_COMMAND_BUFFERS 16000
@@ -137,8 +139,6 @@ private:
ID3D11SamplerState *GetManagedSamplerState();
void DeleteInternalBuffer(int index);
Renderer::Context &getContext();
- static D3D11_PRIMITIVE_TOPOLOGY *m_Topologies;
- static DXGI_FORMAT textureFormats[C4JRender::MAX_TEXTURE_FORMATS];
public:
struct Texture
{
@@ -332,12 +332,12 @@ public:
DWORD stackPos[MATRIX_MODE_MODELVIEW_MAX];
DWORD stackType;
DWORD textureIdx;
- BYTE faceCullEnabled;
- BYTE depthTestEnabled;
- BYTE alphaTestEnabled;
+ bool faceCullEnabled;
+ bool depthTestEnabled;
+ bool alphaTestEnabled;
float alphaReference;
- BYTE depthWriteEnabled;
- BYTE fogEnabled;
+ bool depthWriteEnabled;
+ bool fogEnabled;
float fogNearDistance;
float fogFarDistance;
float fogDensity;
@@ -345,9 +345,9 @@ public:
float fogColourBlue;
float fogColourGreen;
DWORD fogMode;
- BYTE lightingEnabled;
- BYTE lightEnabled[2];
- BYTE lightingDirty;
+ bool lightingEnabled;
+ bool lightEnabled[2];
+ bool lightingDirty;
DWORD forcedLOD;
BYTE paddingAfterForceLOD[4];
DirectX::XMFLOAT4 lightDirection[2];
@@ -377,7 +377,7 @@ public:
DWORD recordingBufferIndex;
DWORD recordingVertexType;
DWORD recordingPrimitiveType;
- BYTE deferredModeEnabled;
+ bool deferredModeEnabled;
std::vector deferredBuffers;
D3D11_BLEND_DESC blendDesc;
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
@@ -386,13 +386,12 @@ public:
};
static DWORD tlsIdx;
- static unsigned int s_auiWidths[MAX_MIP_LEVELS + 1];
- static unsigned int s_auiHeights[MAX_MIP_LEVELS + 1];
- static D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[5];
- static D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_Compressed[2];
- static D3D11_PRIMITIVE_TOPOLOGY g_topologies[C4JRender::PRIMITIVE_TYPE_COUNT];
- static int totalAlloc;
static _RTL_CRITICAL_SECTION totalAllocCS;
+ static DWORD s_auiWidths[];
+ static DWORD s_auiHeights[];
+ static DXGI_FORMAT textureFormats[];
+ static D3D_PRIMITIVE_TOPOLOGY g_topologies[];
+ static int totalAlloc;
float m_fClearColor[4];
ID3D11Device *m_pDevice;
@@ -444,8 +443,8 @@ public:
std::unordered_map managedDepthStencilStates;
std::unordered_map managedSamplerStates;
std::unordered_map managedRasterizerStates;
- BYTE shouldScreenGrabNextFrame;
- BYTE suspended;
+ bool m_bShouldScreenGrabNextFrame;
+ bool m_bSuspended;
BYTE paddingAfterSuspendState[2];
};
diff --git a/Windows_Libs/Dev/Render/RendererCBuff.cpp b/Windows_Libs/Dev/Render/RendererCBuff.cpp
index de1922a..b1fc591 100644
--- a/Windows_Libs/Dev/Render/RendererCBuff.cpp
+++ b/Windows_Libs/Dev/Render/RendererCBuff.cpp
@@ -1,17 +1,19 @@
-#pragma once
+#include "stdafx.h"
#include "Renderer.h"
-#include
-#include
#include
-#include
#include
#include
Renderer::CommandBuffer::CommandBuffer(bool full)
- : m_vertexBuffer(nullptr), m_vertexData(nullptr), m_vertexDataLength(0), m_commands(), m_allocated(0x1000), isActive(full ? 1 : 0)
+ : m_vertexBuffer(NULL)
+ , m_vertexData(NULL)
+ , m_vertexDataLength(0)
+ , m_commands()
+ , m_allocated(0x1000)
+ , isActive(full ? 1 : 0)
{
- m_vertexData = std::malloc(m_allocated);
+ m_vertexData = malloc(m_allocated);
EnterCriticalSection(&Renderer::totalAllocCS);
Renderer::totalAlloc += static_cast(m_allocated);
LeaveCriticalSection(&Renderer::totalAllocCS);
@@ -20,11 +22,9 @@ Renderer::CommandBuffer::CommandBuffer(bool full)
Renderer::CommandBuffer::~CommandBuffer()
{
if (m_vertexBuffer)
- {
m_vertexBuffer->Release();
- }
- std::free(m_vertexData);
+ free(m_vertexData);
EnterCriticalSection(&Renderer::totalAllocCS);
Renderer::totalAlloc -= static_cast(m_allocated);
@@ -38,7 +38,7 @@ void Renderer::CommandBuffer::EndRecording(ID3D11Device *device)
if (m_vertexDataLength != 0)
{
D3D11_BUFFER_DESC desc = {};
- desc.ByteWidth = m_vertexDataLength;
+ desc.ByteWidth = static_cast(m_vertexDataLength);
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
@@ -47,8 +47,8 @@ void Renderer::CommandBuffer::EndRecording(ID3D11Device *device)
device->CreateBuffer(&desc, &data, &m_vertexBuffer);
}
- std::free(m_vertexData);
- m_vertexData = nullptr;
+ free(m_vertexData);
+ m_vertexData = NULL;
}
std::uint64_t Renderer::CommandBuffer::GetAllocated()
@@ -65,15 +65,17 @@ void Renderer::CommandBuffer::AddMatrix(const float *matrix)
{
Command command = {};
command.m_command_type = COMMAND_ADD_MATRIX;
- std::memcpy(command.add_matrix.m_matrix, matrix, sizeof(command.add_matrix.m_matrix));
+ memcpy(command.add_matrix.m_matrix, matrix, sizeof(command.add_matrix.m_matrix));
m_commands.push_back(command);
}
void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int count, void *dataIn, Renderer::Context &c)
{
+ PROFILER_SCOPE("Renderer::CommandBuffer::AddVertices", "AddVertices", MP_ORANGE)
+
if (c.matrixDirty[MATRIX_MODE_MODELVIEW_CBUFF])
{
- this->AddMatrix(InternalRenderManager.MatrixGet(MATRIX_MODE_MODELVIEW_CBUFF));
+ AddMatrix(InternalRenderManager.MatrixGet(MATRIX_MODE_MODELVIEW_CBUFF));
c.matrixDirty[MATRIX_MODE_MODELVIEW_CBUFF] = false;
}
@@ -92,7 +94,7 @@ void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int coun
Renderer::totalAlloc -= static_cast(m_allocated);
LeaveCriticalSection(&Renderer::totalAllocCS);
- m_allocated = ((m_vertexDataLength + (0x1000u - 1u)) & ~(0x1000u - 1u));
+ m_allocated = ((m_vertexDataLength + (0x1000 - 1)) & ~(0x1000 - 1));
m_vertexData = std::realloc(m_vertexData, m_allocated);
EnterCriticalSection(&Renderer::totalAllocCS);
@@ -101,7 +103,7 @@ void Renderer::CommandBuffer::AddVertices(unsigned int stride, unsigned int coun
}
const std::size_t byteCount = std::size_t(stride) * std::size_t(count);
- std::memcpy(static_cast(m_vertexData) + vertexOffset, dataIn, byteCount);
+ memcpy(static_cast(m_vertexData) + vertexOffset, dataIn, byteCount);
m_commands.push_back(command);
}
@@ -243,36 +245,39 @@ void Renderer::CommandBuffer::SetFaceCull(bool enable)
void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Context &c, int primitiveType)
{
+ PROFILER_SCOPE("Renderer::CommandBuffer::Render", "Render", MP_ORANGE)
+
if (!m_vertexBuffer)
- {
return;
- }
int drawVertexType = vType;
int shaderVertexType = drawVertexType;
bool matrixOverride = false;
- for (std::vector::const_iterator it = m_commands.begin(); it != m_commands.end(); ++it)
+ for (const Command &command : m_commands)
{
- const Command &command = *it;
+ PROFILER_SCOPE("Renderer::CommandBuffer::Render", "ProcessCommand", MP_ORANGE)
+
switch (command.m_command_type)
{
case COMMAND_ADD_MATRIX:
{
if (drawVertexType == C4JRender::VERTEX_TYPE_COMPRESSED)
{
- const float row[4] = {command.add_matrix.m_matrix[12], command.add_matrix.m_matrix[13], command.add_matrix.m_matrix[14],
- command.add_matrix.m_matrix[15]};
+ const float row[4] = {
+ command.add_matrix.m_matrix[12], command.add_matrix.m_matrix[13],
+ command.add_matrix.m_matrix[14], command.add_matrix.m_matrix[15]
+ };
D3D11_MAPPED_SUBRESOURCE mappedAux0 = {};
c.m_pDeviceContext->Map(c.m_compressedTranslationBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux0);
- std::memcpy(mappedAux0.pData, row, sizeof(row));
+ memcpy(mappedAux0.pData, row, sizeof(row));
c.m_pDeviceContext->Unmap(c.m_compressedTranslationBuffer, 0);
}
else
{
D3D11_MAPPED_SUBRESOURCE mappedMatrix1 = {};
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix1);
- std::memcpy(mappedMatrix1.pData, command.add_matrix.m_matrix, sizeof(command.add_matrix.m_matrix));
+ memcpy(mappedMatrix1.pData, command.add_matrix.m_matrix, sizeof(command.add_matrix.m_matrix));
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
matrixOverride = true;
}
@@ -300,7 +305,7 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
if (static_cast(drawVertexType) != InternalRenderManager.activeVertexType)
{
- c.m_pDeviceContext->VSSetShader(InternalRenderManager.vertexShaderTable[shaderVertexType], nullptr, 0);
+ c.m_pDeviceContext->VSSetShader(InternalRenderManager.vertexShaderTable[shaderVertexType], NULL, 0);
c.m_pDeviceContext->IASetInputLayout(InternalRenderManager.inputLayoutTable[shaderVertexType]);
InternalRenderManager.activeVertexType = drawVertexType;
}
@@ -310,12 +315,12 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
bool drawIndexed = false;
if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST)
{
- drawCount = (drawCount * 6u) / 4u;
+ drawCount = (drawCount * 6) / 4;
drawIndexed = true;
}
else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN)
{
- drawCount = (drawCount - 2u) * 3u;
+ drawCount = (drawCount - 2) * 3;
drawIndexed = true;
}
@@ -325,13 +330,9 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
c.m_pDeviceContext->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
if (drawIndexed)
- {
c.m_pDeviceContext->DrawIndexed(drawCount, 0, 0);
- }
else
- {
c.m_pDeviceContext->Draw(drawCount, 0);
- }
break;
}
case COMMAND_BIND_TEXTURE:
@@ -346,7 +347,7 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
{
D3D11_MAPPED_SUBRESOURCE mappedColour = {};
c.m_pDeviceContext->Map(c.m_tintColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedColour);
- std::memcpy(mappedColour.pData, command.set_color.m_color, sizeof(command.set_color.m_color));
+ memcpy(mappedColour.pData, command.set_color.m_color, sizeof(command.set_color.m_color));
c.m_pDeviceContext->Unmap(c.m_tintColorBuffer, 0);
break;
}
@@ -358,21 +359,21 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
}
case COMMAND_SET_DEPTH_MASK:
{
- c.depthWriteEnabled = command.set_depth_mask.m_enable ? 1 : 0;
+ c.depthWriteEnabled = command.set_depth_mask.m_enable;
c.depthStencilDesc.DepthWriteMask = command.set_depth_mask.m_enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
break;
}
case COMMAND_SET_DEPTH_TEST:
{
- c.depthTestEnabled = command.set_depth_test.m_enable ? 1 : 0;
- c.depthStencilDesc.DepthEnable = command.set_depth_test.m_enable ? TRUE : FALSE;
+ c.depthTestEnabled = command.set_depth_test.m_enable;
+ c.depthStencilDesc.DepthEnable = command.set_depth_test.m_enable;
c.m_pDeviceContext->OMSetDepthStencilState(InternalRenderManager.GetManagedDepthStencilState(), 0);
break;
}
case COMMAND_SET_LIGHTING_ENABLE:
{
- c.lightingEnabled = command.set_lighting_enable.m_enable ? 1 : 0;
+ c.lightingEnabled = command.set_lighting_enable.m_enable;
break;
}
case COMMAND_SET_LIGHT_ENABLE:
@@ -380,8 +381,8 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
const int light = command.set_light_enable.m_light_index;
if (light >= 0 && light < 2)
{
- c.lightEnabled[light] = command.set_light_enable.m_enable ? 1 : 0;
- c.lightingDirty = 1;
+ c.lightEnabled[light] = command.set_light_enable.m_enable;
+ c.lightingDirty = true;
}
break;
}
@@ -394,7 +395,7 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
c.lightDirection[light].y = command.set_light_direction.m_direction[1];
c.lightDirection[light].z = command.set_light_direction.m_direction[2];
c.lightDirection[light].w = command.set_light_direction.m_direction[3];
- c.lightingDirty = 1;
+ c.lightingDirty = true;
}
break;
}
@@ -407,7 +408,7 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
c.lightColour[light].y = command.set_light_colour.m_color[1];
c.lightColour[light].z = command.set_light_colour.m_color[2];
c.lightColour[light].w = 1.0f;
- c.lightingDirty = 1;
+ c.lightingDirty = true;
}
break;
}
@@ -417,36 +418,36 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
c.lightAmbientColour.y = command.set_light_ambient_colour.m_color[1];
c.lightAmbientColour.z = command.set_light_ambient_colour.m_color[2];
c.lightAmbientColour.w = 1.0f;
- c.lightingDirty = 1;
+ c.lightingDirty = true;
break;
}
case COMMAND_SET_BLEND_ENABLE:
{
- c.blendDesc.RenderTarget[0].BlendEnable = command.set_blend_enable.m_enable ? TRUE : FALSE;
+ c.blendDesc.RenderTarget[0].BlendEnable = command.set_blend_enable.m_enable;
break;
}
case COMMAND_SET_BLEND_FUNC:
{
c.blendDesc.RenderTarget[0].SrcBlend = static_cast(command.set_blend_func.m_src);
c.blendDesc.RenderTarget[0].DestBlend = static_cast(command.set_blend_func.m_dst);
- c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
break;
}
case COMMAND_SET_BLEND_FACTOR:
{
const unsigned int factor = command.set_blend_factor.m_blend_factor;
- c.blendFactor[0] = float((factor >> 0) & 0xFFu) / 255.0f;
- c.blendFactor[1] = float((factor >> 8) & 0xFFu) / 255.0f;
- c.blendFactor[2] = float((factor >> 16) & 0xFFu) / 255.0f;
- c.blendFactor[3] = float((factor >> 24) & 0xFFu) / 255.0f;
- c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.blendFactor[0] = float((factor >> 0) & 0xFF) / 255.0f;
+ c.blendFactor[1] = float((factor >> 8) & 0xFF) / 255.0f;
+ c.blendFactor[2] = float((factor >> 16) & 0xFF) / 255.0f;
+ c.blendFactor[3] = float((factor >> 24) & 0xFF) / 255.0f;
+ c.m_pDeviceContext->OMSetBlendState(InternalRenderManager.GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
break;
}
case COMMAND_SET_FACE_CULL:
{
c.rasterizerDesc.CullMode = command.set_face_cull.m_enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
c.m_pDeviceContext->RSSetState(InternalRenderManager.GetManagedRasterizerState());
- c.faceCullEnabled = command.set_face_cull.m_enable ? 1 : 0;
+ c.faceCullEnabled = command.set_face_cull.m_enable;
break;
}
default:
@@ -459,7 +460,7 @@ void Renderer::CommandBuffer::Render(C4JRender::eVertexType vType, Renderer::Con
const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
D3D11_MAPPED_SUBRESOURCE mappedIdentity = {};
c.m_pDeviceContext->Map(c.m_localTransformMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedIdentity);
- std::memcpy(mappedIdentity.pData, &identity, sizeof(identity));
+ memcpy(mappedIdentity.pData, &identity, sizeof(identity));
c.m_pDeviceContext->Unmap(c.m_localTransformMatrix, 0);
}
}
@@ -472,7 +473,7 @@ bool Renderer::CBuffCall(int index, bool full)
const int commandIndex = m_commandHandleToIndex[index];
if (commandIndex >= 0)
{
- Renderer::Context &c = this->getContext();
+ Renderer::Context &c = getContext();
const std::uint8_t vertexType = m_commandVertexTypes[commandIndex];
const std::uint8_t primitiveType = m_commandPrimitiveTypes[commandIndex];
@@ -482,7 +483,7 @@ bool Renderer::CBuffCall(int index, bool full)
{
D3D11_MAPPED_SUBRESOURCE mappedMatrix0 = {};
c.m_pDeviceContext->Map(c.m_modelViewMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix0);
- std::memcpy(mappedMatrix0.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
+ memcpy(mappedMatrix0.pData, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
c.m_pDeviceContext->Unmap(c.m_modelViewMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW] = false;
}
@@ -491,7 +492,7 @@ bool Renderer::CBuffCall(int index, bool full)
{
D3D11_MAPPED_SUBRESOURCE mappedMatrix2 = {};
c.m_pDeviceContext->Map(c.m_projectionMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix2);
- std::memcpy(mappedMatrix2.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
+ memcpy(mappedMatrix2.pData, MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
c.m_pDeviceContext->Unmap(c.m_projectionMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW_PROJECTION] = false;
}
@@ -500,19 +501,19 @@ bool Renderer::CBuffCall(int index, bool full)
{
D3D11_MAPPED_SUBRESOURCE mappedMatrix3 = {};
c.m_pDeviceContext->Map(c.m_textureMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedMatrix3);
- std::memcpy(mappedMatrix3.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
+ memcpy(mappedMatrix3.pData, MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
c.m_pDeviceContext->Unmap(c.m_textureMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW_TEXTURE] = false;
}
- this->UpdateFogState();
- this->UpdateLightingState();
- this->UpdateViewportState();
- this->UpdateTexGenState();
+ UpdateFogState();
+ UpdateLightingState();
+ UpdateViewportState();
+ UpdateTexGenState();
if (vertexType != activeVertexType)
{
- c.m_pDeviceContext->VSSetShader(vertexShaderTable[vertexType], nullptr, 0);
+ c.m_pDeviceContext->VSSetShader(vertexShaderTable[vertexType], NULL, 0);
c.m_pDeviceContext->IASetInputLayout(inputLayoutTable[vertexType]);
activeVertexType = vertexType;
}
@@ -523,28 +524,24 @@ bool Renderer::CBuffCall(int index, bool full)
const float forcedLod[4] = {static_cast(static_cast(c.forcedLOD)), 0.0f, 0.0f, 0.0f};
D3D11_MAPPED_SUBRESOURCE mappedAux4 = {};
c.m_pDeviceContext->Map(c.m_forcedLODBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedAux4);
- std::memcpy(mappedAux4.pData, forcedLod, sizeof(forcedLod));
+ memcpy(mappedAux4.pData, forcedLod, sizeof(forcedLod));
c.m_pDeviceContext->Unmap(c.m_forcedLODBuffer, 0);
pixelType = C4JRender::PIXEL_SHADER_TYPE_FORCELOD;
}
if (static_cast(pixelType) != activePixelType)
{
- c.m_pDeviceContext->PSSetShader(pixelShaderTable[pixelType], nullptr, 0);
+ c.m_pDeviceContext->PSSetShader(pixelShaderTable[pixelType], NULL, 0);
activePixelType = pixelType;
}
- c.m_pDeviceContext->IASetPrimitiveTopology(m_Topologies[primitiveType]);
+ c.m_pDeviceContext->IASetPrimitiveTopology(g_topologies[primitiveType]);
- ID3D11Buffer *indexBuffer = nullptr;
+ ID3D11Buffer *indexBuffer = NULL;
if (primitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST)
- {
indexBuffer = quadIndexBuffer;
- }
else if (primitiveType == C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN)
- {
indexBuffer = fanIndexBuffer;
- }
c.m_pDeviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0);
}
@@ -553,7 +550,7 @@ bool Renderer::CBuffCall(int index, bool full)
if (full)
{
- this->MultWithStack(m_commandMatrices[commandIndex]);
+ MultWithStack(m_commandMatrices[commandIndex]);
c.matrixStacks[MATRIX_MODE_MODELVIEW_CBUFF][0] = DirectX::XMMatrixIdentity();
c.matrixDirty[MATRIX_MODE_MODELVIEW_CBUFF] = true;
}
@@ -573,7 +570,7 @@ void Renderer::CBuffClear(int index)
const int internalIndex = externalToInternal[index];
if (internalIndex >= 0)
{
- this->DeleteInternalBuffer(internalIndex);
+ DeleteInternalBuffer(internalIndex);
externalToInternal[index] = static_cast(-2);
}
@@ -600,9 +597,7 @@ int Renderer::CBuffCreate(int count)
}
if (cursor >= end)
- {
break;
- }
++first;
++probe;
@@ -618,14 +613,10 @@ int Renderer::CBuffCreate(int count)
{
const int allocationEnd = first + count;
for (int i = first; i < allocationEnd; ++i)
- {
m_commandHandleToIndex[i] = static_cast(-2);
- }
if (reservedRendererByte1)
- {
reservedRendererDword1 = allocationEnd;
- }
}
}
else
@@ -639,28 +630,22 @@ int Renderer::CBuffCreate(int count)
void Renderer::CBuffDeferredModeEnd()
{
- Renderer::Context &c = this->getContext();
+ Renderer::Context &c = getContext();
if (!c.deferredModeEnabled)
- {
return;
- }
EnterCriticalSection(&rtl_critical_section100);
- c.deferredModeEnabled = 0;
+ c.deferredModeEnabled = false;
for (std::vector::const_iterator it = c.deferredBuffers.begin(); it != c.deferredBuffers.end(); ++it)
{
const Renderer::DeferredCBuff &deferred = *it;
const int existingIndex = m_commandHandleToIndex[deferred.m_vertex_index];
if (existingIndex >= 0)
- {
- this->DeleteInternalBuffer(existingIndex);
- }
+ DeleteInternalBuffer(existingIndex);
- if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10u) > MAX_COMMAND_BUFFERS)
- {
+ if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10) > MAX_COMMAND_BUFFERS)
DebugBreak();
- }
const int internalSlot = reservedRendererDword2;
++reservedRendererDword2;
@@ -679,7 +664,7 @@ void Renderer::CBuffDeferredModeEnd()
void Renderer::CBuffDeferredModeStart()
{
- this->getContext().deferredModeEnabled = 1;
+ getContext().deferredModeEnabled = true;
}
void Renderer::CBuffDelete(int first, int count)
@@ -691,9 +676,7 @@ void Renderer::CBuffDelete(int first, int count)
{
const int internalIndex = m_commandHandleToIndex[i];
if (internalIndex >= 0)
- {
- this->DeleteInternalBuffer(internalIndex);
- }
+ DeleteInternalBuffer(internalIndex);
m_commandHandleToIndex[i] = static_cast(-1);
}
@@ -703,7 +686,7 @@ void Renderer::CBuffDelete(int first, int count)
void Renderer::CBuffEnd()
{
- Renderer::Context &c = this->getContext();
+ Renderer::Context &c = getContext();
assert(c.stackType == MATRIX_MODE_MODELVIEW_CBUFF);
assert(c.stackPos[MATRIX_MODE_MODELVIEW_CBUFF] == 0);
@@ -724,14 +707,10 @@ void Renderer::CBuffEnd()
{
const int existingIndex = m_commandHandleToIndex[c.recordingBufferIndex];
if (existingIndex >= 0)
- {
- this->DeleteInternalBuffer(existingIndex);
- }
+ DeleteInternalBuffer(existingIndex);
- if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10u) > MAX_COMMAND_BUFFERS)
- {
+ if (static_cast(reservedRendererDword2 + reservedRendererDword3 + 10) > MAX_COMMAND_BUFFERS)
DebugBreak();
- }
const int internalSlot = reservedRendererDword2;
++reservedRendererDword2;
@@ -746,7 +725,7 @@ void Renderer::CBuffEnd()
c.stackType = MATRIX_MODE_MODELVIEW;
c.commandBuffer->EndRecording(m_pDevice);
- c.commandBuffer = nullptr;
+ c.commandBuffer = NULL;
LeaveCriticalSection(&rtl_critical_section100);
}
@@ -759,24 +738,20 @@ void Renderer::CBuffLockStaticCreations()
int Renderer::CBuffSize(int index)
{
if (index == -1)
- {
return totalAlloc < 0 ? 0 : totalAlloc;
- }
unsigned int size = 0;
EnterCriticalSection(&rtl_critical_section100);
const int commandIndex = m_commandHandleToIndex[index];
if (commandIndex >= 0)
- {
- size = m_commandBuffers[commandIndex]->GetAllocated();
- }
+ size = static_cast(m_commandBuffers[commandIndex]->GetAllocated());
LeaveCriticalSection(&rtl_critical_section100);
return size;
}
void Renderer::CBuffStart(int index, bool full)
{
- Renderer::Context &c = this->getContext();
+ Renderer::Context &c = getContext();
c.commandBuffer = new (std::nothrow) Renderer::CommandBuffer(full);
c.recordingBufferIndex = index;
@@ -797,10 +772,8 @@ void Renderer::CBuffTick()
{
Renderer::CommandBuffer *buffer = m_commandBuffers[i];
if (buffer)
- {
delete buffer;
- }
- m_commandBuffers[i] = nullptr;
+ m_commandBuffers[i] = NULL;
}
reservedRendererDword3 = 0;
@@ -832,4 +805,4 @@ void Renderer::DeleteInternalBuffer(int index)
}
LeaveCriticalSection(&rtl_critical_section100);
-}
+}
\ No newline at end of file
diff --git a/Windows_Libs/Dev/Render/RendererCore.cpp b/Windows_Libs/Dev/Render/RendererCore.cpp
index c472f74..1cd8139 100644
--- a/Windows_Libs/Dev/Render/RendererCore.cpp
+++ b/Windows_Libs/Dev/Render/RendererCore.cpp
@@ -1,41 +1,25 @@
-#pragma once
-#include "CompiledShaders.h"
+#include "stdafx.h"
#include "Renderer.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
+#include "CompiledShaders.h"
Renderer InternalRenderManager;
DWORD Renderer::tlsIdx = TlsAlloc();
+_RTL_CRITICAL_SECTION Renderer::totalAllocCS;
+
+DWORD Renderer::s_auiWidths[] = { 1920, 512, 256, 128, 64, 0 };
+DWORD Renderer::s_auiHeights[] = { 1080, 512, 256, 128, 64 };
int Renderer::totalAlloc = 0;
-_RTL_CRITICAL_SECTION Renderer::totalAllocCS = {0};
-static const unsigned int kVertexBufferSize = 0x100000u;
-static const float kAspectRatio = 1.7777778f;
-static const unsigned int kScreenGrabWidth = 1920u;
-static const unsigned int kScreenGrabHeight = 1080u;
-static const unsigned int kThumbnailSize = 64u;
-
-static const unsigned int g_vertexStrides[C4JRender::VERTEX_TYPE_COUNT] = {32u, 16u, 32u, 32u};
-
-unsigned int Renderer::s_auiWidths[MAX_MIP_LEVELS + 1] = {1920u, 512u, 256u, 128u, 64u, 0u};
-
-unsigned int Renderer::s_auiHeights[MAX_MIP_LEVELS + 1] = {1080u, 512u, 256u, 128u, 64u, 0xFFFFFFFFu};
-
-D3D11_INPUT_ELEMENT_DESC Renderer::g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[5] = {
- {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"NORMAL", 0, DXGI_FORMAT_R8G8B8A8_SNORM, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"TEXCOORD", 1, DXGI_FORMAT_R16G16_SINT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
+D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1[] = {
+ {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"NORMAL", 0, DXGI_FORMAT_R8G8B8A8_SNORM, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 1, DXGI_FORMAT_R16G16_SINT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
-D3D11_INPUT_ELEMENT_DESC Renderer::g_vertex_PTN_Elements_Compressed[2] = {
+D3D11_INPUT_ELEMENT_DESC g_vertex_PTN_Elements_Compressed[] = {
{"POSITION", 0, DXGI_FORMAT_R16G16B16A16_SINT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R16G16B16A16_SINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
@@ -45,43 +29,88 @@ D3D11_PRIMITIVE_TOPOLOGY Renderer::g_topologies[C4JRender::PRIMITIVE_TYPE_COUNT]
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, D3D11_PRIMITIVE_TOPOLOGY_LINELIST, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
};
-Renderer::Context::Context(ID3D11Device *device, ID3D11DeviceContext *deviceContext)
- : m_pDeviceContext(deviceContext), userAnnotation(nullptr), annotateDepth(0), stackType(0), textureIdx(0), faceCullEnabled(1),
- depthTestEnabled(1), alphaTestEnabled(0), alphaReference(1.0f), depthWriteEnabled(1), fogEnabled(0), fogNearDistance(0.0f),
- fogFarDistance(0.0f), fogDensity(0.0f), fogColourRed(0.0f), fogColourBlue(0.0f), fogColourGreen(0.0f), fogMode(0), lightingEnabled(0),
- lightingDirty(0), forcedLOD(0xFFFFFFFFu), m_modelViewMatrix(nullptr), m_localTransformMatrix(nullptr), m_projectionMatrix(nullptr),
- m_textureMatrix(nullptr), m_vertexTexcoordBuffer(nullptr), m_fogParamsBuffer(nullptr), m_lightingStateBuffer(nullptr), m_texGenMatricesBuffer(nullptr),
- m_compressedTranslationBuffer(nullptr), m_thumbnailBoundsBuffer(nullptr), m_tintColorBuffer(nullptr), m_fogColourBuffer(nullptr), m_unkColorBuffer(nullptr), m_alphaTestBuffer(nullptr),
- m_clearColorBuffer(nullptr), m_forcedLODBuffer(nullptr), dynamicVertexBase(0), dynamicVertexOffset(0), dynamicVertexBuffer(nullptr),
- commandBuffer(nullptr), recordingBufferIndex(0), recordingVertexType(0), recordingPrimitiveType(0), deferredModeEnabled(0), deferredBuffers()
+static const unsigned int kVertexBufferSize = 0x100000;
+static const unsigned int kScreenGrabWidth = 1920;
+static const unsigned int kScreenGrabHeight = 1080;
+static const unsigned int kThumbnailSize = 64;
+
+static const unsigned int g_vertexStrides[C4JRender::VERTEX_TYPE_COUNT] = { 32, 16, 32, 32 };
+
+Renderer::Context::Context(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
+ : m_pDeviceContext(deviceContext)
+ , userAnnotation(NULL)
+ , annotateDepth(0)
+ , stackType(0)
+ , textureIdx(0)
+ , faceCullEnabled(true)
+ , depthTestEnabled(true)
+ , depthWriteEnabled(true)
+ , alphaTestEnabled(false)
+ , alphaReference(1.0f)
+ , fogEnabled(false)
+ , fogNearDistance(0.0f)
+ , fogFarDistance(0.0f)
+ , fogDensity(0.0f)
+ , fogColourRed(0.0f)
+ , fogColourGreen(0.0f)
+ , fogColourBlue(0.0f)
+ , fogMode(0)
+ , lightingEnabled(false)
+ , lightingDirty(false)
+ , forcedLOD(-1)
+ , m_modelViewMatrix(NULL)
+ , m_localTransformMatrix(NULL)
+ , m_projectionMatrix(NULL)
+ , m_textureMatrix(NULL)
+ , m_vertexTexcoordBuffer(NULL)
+ , m_fogParamsBuffer(NULL)
+ , m_lightingStateBuffer(NULL)
+ , m_texGenMatricesBuffer(NULL)
+ , m_compressedTranslationBuffer(NULL)
+ , m_thumbnailBoundsBuffer(NULL)
+ , m_tintColorBuffer(NULL)
+ , m_fogColourBuffer(NULL)
+ , m_unkColorBuffer(NULL)
+ , m_alphaTestBuffer(NULL)
+ , m_clearColorBuffer(NULL)
+ , m_forcedLODBuffer(NULL)
+ , dynamicVertexBase(0)
+ , dynamicVertexOffset(0)
+ , dynamicVertexBuffer(NULL)
+ , commandBuffer(NULL)
+ , recordingBufferIndex(0)
+ , recordingVertexType(0)
+ , recordingPrimitiveType(0)
+ , deferredModeEnabled(false)
+ , deferredBuffers()
{
deviceContext->QueryInterface(IID_PPV_ARGS(&userAnnotation));
- std::memset(matrixStacks, 0, sizeof(matrixStacks));
- std::memset(matrixDirty, 0, sizeof(matrixDirty));
- std::memset(stackPos, 0, sizeof(stackPos));
- std::memset(lightEnabled, 0, sizeof(lightEnabled));
- std::memset(lightDirection, 0, sizeof(lightDirection));
- std::memset(lightColour, 0, sizeof(lightColour));
- std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour));
- std::memset(texGenMatrices, 0, sizeof(texGenMatrices));
- std::memset(&blendDesc, 0, sizeof(blendDesc));
- std::memset(&depthStencilDesc, 0, sizeof(depthStencilDesc));
- std::memset(&rasterizerDesc, 0, sizeof(rasterizerDesc));
+ memset(matrixStacks, 0, sizeof(matrixStacks));
+ memset(matrixDirty, 0, sizeof(matrixDirty));
+ memset(stackPos, 0, sizeof(stackPos));
+ memset(lightEnabled, 0, sizeof(lightEnabled));
+ memset(lightDirection, 0, sizeof(lightDirection));
+ memset(lightColour, 0, sizeof(lightColour));
+ memset(&lightAmbientColour, 0, sizeof(lightAmbientColour));
+ memset(texGenMatrices, 0, sizeof(texGenMatrices));
+ memset(&blendDesc, 0, sizeof(blendDesc));
+ memset(&depthStencilDesc, 0, sizeof(depthStencilDesc));
+ memset(&rasterizerDesc, 0, sizeof(rasterizerDesc));
blendFactor[0] = 0.0f;
blendFactor[1] = 0.0f;
blendFactor[2] = 0.0f;
blendFactor[3] = 0.0f;
const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
- for (unsigned int i = 0; i < MATRIX_MODE_MODELVIEW_MAX; ++i)
+ for (UINT i = 0; i < MATRIX_MODE_MODELVIEW_MAX; ++i)
{
matrixStacks[i][0] = identity;
stackPos[i] = 0;
}
- blendDesc.AlphaToCoverageEnable = FALSE;
- blendDesc.IndependentBlendEnable = FALSE;
- blendDesc.RenderTarget[0].BlendEnable = FALSE;
+ blendDesc.AlphaToCoverageEnable = false;
+ blendDesc.IndependentBlendEnable = false;
+ blendDesc.RenderTarget[0].BlendEnable = false;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
@@ -90,12 +119,12 @@ Renderer::Context::Context(ID3D11Device *device, ID3D11DeviceContext *deviceCont
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
- depthStencilDesc.DepthEnable = TRUE;
+ depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
- depthStencilDesc.StencilEnable = FALSE;
- depthStencilDesc.StencilReadMask = 0xFFu;
- depthStencilDesc.StencilWriteMask = 0xFFu;
+ depthStencilDesc.StencilEnable = false;
+ depthStencilDesc.StencilReadMask = 0xFF;
+ depthStencilDesc.StencilWriteMask = 0xFF;
depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
@@ -107,19 +136,19 @@ Renderer::Context::Context(ID3D11Device *device, ID3D11DeviceContext *deviceCont
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.CullMode = D3D11_CULL_BACK;
- rasterizerDesc.FrontCounterClockwise = TRUE;
+ rasterizerDesc.FrontCounterClockwise = true;
rasterizerDesc.DepthBias = 0;
rasterizerDesc.DepthBiasClamp = 0.0f;
rasterizerDesc.SlopeScaledDepthBias = 0.0f;
- rasterizerDesc.DepthClipEnable = TRUE;
- rasterizerDesc.ScissorEnable = FALSE;
- rasterizerDesc.MultisampleEnable = TRUE;
- rasterizerDesc.AntialiasedLineEnable = FALSE;
+ rasterizerDesc.DepthClipEnable = true;
+ rasterizerDesc.ScissorEnable = false;
+ rasterizerDesc.MultisampleEnable = true;
+ rasterizerDesc.AntialiasedLineEnable = false;
- std::memset(lightDirection, 0, sizeof(lightDirection));
- std::memset(lightColour, 0, sizeof(lightColour));
- std::memset(&lightAmbientColour, 0, sizeof(lightAmbientColour));
- std::memset(texGenMatrices, 0, sizeof(texGenMatrices));
+ memset(lightDirection, 0, sizeof(lightDirection));
+ memset(lightColour, 0, sizeof(lightColour));
+ memset(&lightAmbientColour, 0, sizeof(lightAmbientColour));
+ memset(texGenMatrices, 0, sizeof(texGenMatrices));
const float zero4[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float one4[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -186,7 +215,7 @@ Renderer::Context::Context(ID3D11Device *device, ID3D11DeviceContext *deviceCont
vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- device->CreateBuffer(&vbDesc, nullptr, &dynamicVertexBuffer);
+ device->CreateBuffer(&vbDesc, NULL, &dynamicVertexBuffer);
}
void Renderer::BeginConditionalRendering(int) {}
@@ -197,16 +226,19 @@ void Renderer::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {}
void Renderer::Clear(int flags, D3D11_RECT *)
{
- Renderer::Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::Clear", "Clear", MP_MAGENTA)
- ID3D11BlendState *blendState = nullptr;
- ID3D11DepthStencilState *depthState = nullptr;
- ID3D11RasterizerState *rasterizerState = nullptr;
+ Renderer::Context &c = getContext();
+ ID3D11BlendState *blendState = NULL;
+ ID3D11DepthStencilState *depthState = NULL;
+ ID3D11RasterizerState *rasterizerState = NULL;
+
+ PROFILER_SCOPE("Renderer::Clear", "Blend", MP_MAGENTA)
D3D11_BLEND_DESC blendDesc = {};
- blendDesc.AlphaToCoverageEnable = FALSE;
- blendDesc.IndependentBlendEnable = FALSE;
- blendDesc.RenderTarget[0].BlendEnable = FALSE;
+ blendDesc.AlphaToCoverageEnable = false;
+ blendDesc.IndependentBlendEnable = false;
+ blendDesc.RenderTarget[0].BlendEnable = false;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
@@ -216,13 +248,14 @@ void Renderer::Clear(int flags, D3D11_RECT *)
blendDesc.RenderTarget[0].RenderTargetWriteMask = (flags & CLEAR_COLOUR_FLAG) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0;
m_pDevice->CreateBlendState(&blendDesc, &blendState);
+ PROFILER_SCOPE("Renderer::Clear", "Depth", MP_MAGENTA)
D3D11_DEPTH_STENCIL_DESC depthDesc = {};
- depthDesc.DepthEnable = (flags & CLEAR_DEPTH_FLAG) ? TRUE : FALSE;
+ depthDesc.DepthEnable = (flags & CLEAR_DEPTH_FLAG) ? true : false;
depthDesc.DepthWriteMask = depthDesc.DepthEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
- depthDesc.StencilEnable = FALSE;
- depthDesc.StencilReadMask = 0xFFu;
- depthDesc.StencilWriteMask = 0xFFu;
+ depthDesc.StencilEnable = false;
+ depthDesc.StencilReadMask = 0xFF;
+ depthDesc.StencilWriteMask = 0xFF;
depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
@@ -233,70 +266,79 @@ void Renderer::Clear(int flags, D3D11_RECT *)
depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
m_pDevice->CreateDepthStencilState(&depthDesc, &depthState);
+ PROFILER_SCOPE("Renderer::Clear", "Rasterizer", MP_MAGENTA)
D3D11_RASTERIZER_DESC rasterDesc = {};
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.CullMode = D3D11_CULL_NONE;
- rasterDesc.DepthClipEnable = TRUE;
- rasterDesc.MultisampleEnable = TRUE;
+ rasterDesc.DepthClipEnable = true;
+ rasterDesc.MultisampleEnable = true;
m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState);
- c.m_pDeviceContext->VSSetShader(screenClearVertexShader, nullptr, 0);
- c.m_pDeviceContext->IASetInputLayout(nullptr);
- c.m_pDeviceContext->PSSetShader(screenClearPixelShader, nullptr, 0);
+ PROFILER_SCOPE("Renderer::Clear", "DrawClearQuad", MP_MAGENTA)
+ c.m_pDeviceContext->VSSetShader(screenClearVertexShader, NULL, 0);
+ c.m_pDeviceContext->IASetInputLayout(NULL);
+ c.m_pDeviceContext->PSSetShader(screenClearPixelShader, NULL, 0);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
- c.m_pDeviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFFFu);
+ c.m_pDeviceContext->OMSetBlendState(blendState, NULL, 0xFFFFFFFF);
c.m_pDeviceContext->OMSetDepthStencilState(depthState, 0);
c.m_pDeviceContext->RSSetState(rasterizerState);
- c.m_pDeviceContext->PSSetShaderResources(0, 0, nullptr);
+ c.m_pDeviceContext->PSSetShaderResources(0, 0, NULL);
c.m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
c.m_pDeviceContext->Draw(4, 0);
if (blendState)
{
blendState->Release();
- blendState = nullptr;
+ blendState = NULL;
}
if (depthState)
{
depthState->Release();
- depthState = nullptr;
+ depthState = NULL;
}
if (rasterizerState)
{
rasterizerState->Release();
- rasterizerState = nullptr;
+ rasterizerState = NULL;
}
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
- c.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0);
- c.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState());
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
+ c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
+ c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
- activeVertexType = 0xFFFFFFFFu;
- activePixelType = 0xFFFFFFFFu;
+
+ activeVertexType = -1;
+ activePixelType = -1;
}
void Renderer::ConvertLinearToPng(ImageFileBuffer *pngOut, unsigned char *linearData, unsigned int width, unsigned int height)
{
- const size_t dataSize = size_t(width) * size_t(height) * 4u;
- const size_t outputCapacity = ((dataSize * 24u) / 20u) + 256u;
- const int outputCapacityInt = int(outputCapacity);
- const int widthInt = int(width);
- const int heightInt = int(height);
- void *outputBuffer = std::malloc(outputCapacity);
+ const size_t dataSize = static_cast(width) * static_cast(height) * 4;
+ const size_t outputCapacity = (dataSize * 24) / 20 + 256;
+
+ void *outputBuffer = malloc(outputCapacity);
int outputLength = 0;
- this->SaveTextureDataToMemory(outputBuffer, outputCapacityInt, &outputLength, widthInt, heightInt, reinterpret_cast(linearData));
+
+ SaveTextureDataToMemory(
+ outputBuffer,
+ static_cast(outputCapacity),
+ &outputLength,
+ static_cast(width),
+ static_cast(height),
+ reinterpret_cast(linearData)
+ );
+
pngOut->m_type = ImageFileBuffer::e_typePNG;
pngOut->m_pBuffer = outputBuffer;
pngOut->m_bufferSize = outputLength;
}
-void Renderer::DoScreenGrabOnNextPresent()
-{
- shouldScreenGrabNextFrame = 1;
+void Renderer::DoScreenGrabOnNextPresent()
+{
+ m_bShouldScreenGrabNextFrame = true;
}
void Renderer::EndConditionalRendering() {}
-
void Renderer::EndConditionalSurvey() {}
void Renderer::BeginEvent(LPCWSTR eventName)
@@ -315,7 +357,6 @@ void Renderer::EndEvent()
if (c.m_pDeviceContext->GetType() != D3D11_DEVICE_CONTEXT_DEFERRED && c.userAnnotation)
{
c.userAnnotation->EndEvent();
-
--c.annotateDepth;
assert(c.annotateDepth >= 0);
}
@@ -324,9 +365,14 @@ void Renderer::EndEvent()
void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
{
m_pDevice = pDevice;
- m_pDeviceContext = this->InitialiseContext(true);
+ m_pDeviceContext = InitialiseContext(true);
m_pSwapChain = pSwapChain;
+ #ifdef ENABLE_PROFILING
+ MicroProfileOnThreadCreate("MainRenderThread");
+ MicroProfileSetEnableAllGroups(true);
+ #endif
+
m_commandHandleToIndex = new int16_t[NUM_COMMAND_HANDLES];
m_commandBuffers = new CommandBuffer *[MAX_COMMAND_BUFFERS];
m_commandMatrices = new DirectX::XMMATRIX[MAX_COMMAND_BUFFERS];
@@ -334,24 +380,24 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
m_commandVertexTypes = new uint8_t[MAX_COMMAND_BUFFERS];
m_commandPrimitiveTypes = new uint8_t[MAX_COMMAND_BUFFERS];
- std::memset(m_commandHandleToIndex, 0xFF, NUM_COMMAND_HANDLES);
- std::memset(m_commandBuffers, 0, MAX_COMMAND_BUFFERS);
- std::memset(m_commandIndexToHandle, 0, MAX_COMMAND_BUFFERS);
- std::memset(m_commandVertexTypes, 0, MAX_COMMAND_BUFFERS);
- std::memset(m_commandPrimitiveTypes, 0, MAX_COMMAND_BUFFERS);
+ memset(m_commandHandleToIndex, 0xFF, NUM_COMMAND_HANDLES * sizeof(int16_t));
+ memset(m_commandBuffers, 0, MAX_COMMAND_BUFFERS * sizeof(CommandBuffer*));
+ memset(m_commandIndexToHandle, 0, MAX_COMMAND_BUFFERS * sizeof(int));
+ memset(m_commandVertexTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t));
+ memset(m_commandPrimitiveTypes, 0, MAX_COMMAND_BUFFERS * sizeof(uint8_t));
reservedRendererDword3 = 0;
+ m_bShouldScreenGrabNextFrame = false;
+ m_bSuspended = false;
- shouldScreenGrabNextFrame = 0;
- suspended = 0;
-
- this->SetupShaders();
+ SetupShaders();
const float clearColour[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- this->SetClearColour(clearColour);
+ SetClearColour(clearColour);
UINT backBufferSampleCount = 1;
UINT backBufferSampleQuality = 0;
- ID3D11Texture2D *backBuffer = nullptr;
+
+ ID3D11Texture2D *backBuffer = NULL;
pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
if (backBuffer)
{
@@ -361,17 +407,24 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
backBufferHeight = backDesc.Height;
backBufferSampleCount = backDesc.SampleDesc.Count;
backBufferSampleQuality = backDesc.SampleDesc.Quality;
- m_pDevice->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView);
- m_pDevice->CreateShaderResourceView(backBuffer, nullptr, &renderTargetShaderResourceView);
+
+ m_pDevice->CreateRenderTargetView(backBuffer, NULL, &renderTargetView);
+
+ D3D11_TEXTURE2D_DESC srvDesc = backDesc;
+ srvDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+ srvDesc.MiscFlags = 0;
+
+ ID3D11Texture2D *srvTexture = NULL;
+ m_pDevice->CreateTexture2D(&srvDesc, NULL, &srvTexture);
+ m_pDevice->CreateShaderResourceView(srvTexture, NULL, &renderTargetShaderResourceView);
+
+ srvTexture->Release();
backBuffer->Release();
}
- ID3D11RenderTargetView *boundRTV = nullptr;
+ ID3D11RenderTargetView *boundRTV = NULL;
m_pDeviceContext->OMGetRenderTargets(1, &boundRTV, &depthStencilView);
- if (boundRTV)
- {
- boundRTV->Release();
- }
+ if (boundRTV) boundRTV->Release();
if (!depthStencilView && backBufferWidth != 0 && backBufferHeight != 0)
{
@@ -386,15 +439,15 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
depthDesc.Usage = D3D11_USAGE_DEFAULT;
depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
- ID3D11Texture2D *depthTexture = nullptr;
- if (SUCCEEDED(m_pDevice->CreateTexture2D(&depthDesc, nullptr, &depthTexture)))
+ ID3D11Texture2D *depthTexture = NULL;
+ if (SUCCEEDED(m_pDevice->CreateTexture2D(&depthDesc, NULL, &depthTexture)))
{
- m_pDevice->CreateDepthStencilView(depthTexture, nullptr, &depthStencilView);
+ m_pDevice->CreateDepthStencilView(depthTexture, NULL, &depthStencilView);
depthTexture->Release();
}
}
- for (unsigned int i = 0; i < MAX_MIP_LEVELS - 1; ++i)
+ for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i)
{
D3D11_TEXTURE2D_DESC desc = {};
desc.Width = s_auiWidths[i + 1];
@@ -406,98 +459,97 @@ void Renderer::Initialise(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain)
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
- HRESULT hr = 0;
- hr = m_pDevice->CreateTexture2D(&desc, nullptr, &renderTargetTextures[i]);
+ HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &renderTargetTextures[i]);
assert(hr == S_OK);
- hr = m_pDevice->CreateRenderTargetView(renderTargetTextures[i], nullptr, &renderTargetViews[i]);
+ hr = m_pDevice->CreateRenderTargetView(renderTargetTextures[i], NULL, &renderTargetViews[i]);
assert(hr == S_OK);
- hr = m_pDevice->CreateShaderResourceView(renderTargetTextures[i], nullptr, &renderTargetShaderResourceViews[i]);
+ hr = m_pDevice->CreateShaderResourceView(renderTargetTextures[i], NULL, &renderTargetShaderResourceViews[i]);
assert(hr == S_OK);
}
- std::memset(m_textures, 0, sizeof(m_textures));
- defaultTextureIndex = this->TextureCreate();
- this->TextureBind(defaultTextureIndex);
+ memset(m_textures, 0, sizeof(m_textures));
+ defaultTextureIndex = TextureCreate();
+ TextureBind(defaultTextureIndex);
- unsigned char *defaultTextureData = new unsigned char[0x400u];
- std::memset(defaultTextureData, 0xFF, 0x400u);
- this->TextureData(16, 16, defaultTextureData, 0, C4JRender::TEXTURE_FORMAT_RxGyBzAw);
+ unsigned char *defaultTextureData = new unsigned char[0x400];
+ memset(defaultTextureData, 0xFF, 0x400);
+ TextureData(16, 16, defaultTextureData, 0, C4JRender::TEXTURE_FORMAT_RxGyBzAw);
delete[] defaultTextureData;
presentCount = 0;
rendererFlag0 = 0;
reservedRendererWord0 = 10922;
- this->StateSetViewport(C4JRender::VIEWPORT_TYPE_FULLSCREEN);
- this->StateSetVertexTextureUV(0.0f, 0.0f);
- this->TextureBindVertex(-1);
+ StateSetViewport(C4JRender::VIEWPORT_TYPE_FULLSCREEN);
+ StateSetVertexTextureUV(0.0f, 0.0f);
+ TextureBindVertex(-1);
+
InitializeCriticalSection(&rtl_critical_section100);
+ InitializeCriticalSection(&Renderer::totalAllocCS);
+
reservedRendererDword1 = 0;
- activeVertexType = 0xFFFFFFFFu;
- activePixelType = 0xFFFFFFFFu;
+ activeVertexType = -1;
+ activePixelType = -1;
reservedRendererByte1 = 1;
reservedRendererByte0 = 0;
- unsigned short *quadIndices = new unsigned short[0x18000u];
- for (unsigned int i = 0; i < 0x4000u; ++i)
+ unsigned short *quadIndices = new unsigned short[0x18000];
+ for (UINT i = 0; i < 0x4000; ++i)
{
- const unsigned short base = (unsigned short)(i * 4u);
- const unsigned int offset = i * 6u;
+ unsigned short base = static_cast(i * 4);
+ unsigned int offset = i * 6;
quadIndices[offset + 0] = base;
- quadIndices[offset + 1] = (unsigned short)(base + 1u);
- quadIndices[offset + 2] = (unsigned short)(base + 3u);
- quadIndices[offset + 3] = (unsigned short)(base + 1u);
- quadIndices[offset + 4] = (unsigned short)(base + 2u);
- quadIndices[offset + 5] = (unsigned short)(base + 3u);
+ quadIndices[offset + 1] = base + 1;
+ quadIndices[offset + 2] = base + 3;
+ quadIndices[offset + 3] = base + 1;
+ quadIndices[offset + 4] = base + 2;
+ quadIndices[offset + 5] = base + 3;
}
+
D3D11_BUFFER_DESC quadIndexDesc = {};
- quadIndexDesc.ByteWidth = 0x30000u;
+ quadIndexDesc.ByteWidth = 0x30000;
quadIndexDesc.Usage = D3D11_USAGE_IMMUTABLE;
quadIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+
D3D11_SUBRESOURCE_DATA quadIndexData = {};
quadIndexData.pSysMem = quadIndices;
-
HRESULT hr = m_pDevice->CreateBuffer(&quadIndexDesc, &quadIndexData, &quadIndexBuffer);
assert(hr >= 0);
-
delete[] quadIndices;
- unsigned short *fanIndices = new unsigned short[0x2FFFAu];
- for (unsigned int i = 0; i < 65534u; ++i)
+ unsigned short *fanIndices = new unsigned short[0x2FFFA];
+ for (UINT i = 0; i < 65534; ++i)
{
- const unsigned int offset = i * 3u;
- fanIndices[offset + 0] = 0u;
- fanIndices[offset + 1] = (unsigned short)(i + 1u);
- fanIndices[offset + 2] = (unsigned short)(i + 2u);
+ unsigned int offset = i * 3;
+ fanIndices[offset + 0] = 0;
+ fanIndices[offset + 1] = static_cast(i + 1);
+ fanIndices[offset + 2] = static_cast(i + 2);
}
+
D3D11_BUFFER_DESC fanIndexDesc = {};
- fanIndexDesc.ByteWidth = 0x5FFF4u;
+ fanIndexDesc.ByteWidth = 0x5FFF4;
fanIndexDesc.Usage = D3D11_USAGE_IMMUTABLE;
fanIndexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+
D3D11_SUBRESOURCE_DATA fanIndexData = {};
fanIndexData.pSysMem = fanIndices;
m_pDevice->CreateBuffer(&fanIndexDesc, &fanIndexData, &fanIndexBuffer);
delete[] fanIndices;
-
- InitializeCriticalSection(&Renderer::totalAllocCS);
- m_Topologies = g_topologies;
}
ID3D11DeviceContext *Renderer::InitialiseContext(bool fromPresent)
{
- ID3D11DeviceContext *deviceContext = nullptr;
+ ID3D11DeviceContext *deviceContext = NULL;
+
if (fromPresent)
- {
m_pDevice->GetImmediateContext(&deviceContext);
- }
else
- {
m_pDevice->CreateDeferredContext(0, &deviceContext);
- }
Renderer::Context *c = new (std::nothrow) Renderer::Context(m_pDevice, deviceContext);
TlsSetValue(Renderer::tlsIdx, c);
+
return deviceContext;
}
@@ -513,11 +565,16 @@ bool Renderer::IsWidescreen()
void Renderer::Present()
{
- if (shouldScreenGrabNextFrame)
+ PROFILER_SCOPE("Renderer::Present", "Present", MP_MAGENTA)
+
+ if (m_bShouldScreenGrabNextFrame)
{
- int *linearData = new int[kScreenGrabWidth * kScreenGrabHeight];
- ID3D11Texture2D *backBuffer = nullptr;
- ID3D11Texture2D *stagingTexture = nullptr;
+ PROFILER_SCOPE("Renderer::Present", "ScreenGrab", MP_MAGENTA)
+
+ unsigned char *linearData = new unsigned char[kScreenGrabWidth * kScreenGrabHeight * 4];
+
+ ID3D11Texture2D *backBuffer = NULL;
+ ID3D11Texture2D *stagingTexture = NULL;
m_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
if (backBuffer)
@@ -528,27 +585,29 @@ void Renderer::Present()
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
- m_pDevice->CreateTexture2D(&desc, nullptr, &stagingTexture);
+ m_pDevice->CreateTexture2D(&desc, NULL, &stagingTexture);
}
if (stagingTexture && backBuffer)
{
+ PROFILER_SCOPE("Renderer::Present", "CopyResource", MP_MAGENTA)
m_pDeviceContext->CopyResource(stagingTexture, backBuffer);
+
D3D11_MAPPED_SUBRESOURCE mapped = {};
if (SUCCEEDED(m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapped)))
{
- unsigned char *dst = reinterpret_cast(linearData);
const unsigned char *src = reinterpret_cast(mapped.pData);
- for (unsigned int y = 0; y < kScreenGrabHeight; ++y)
+
+ for (UINT y = 0; y < kScreenGrabHeight; ++y)
{
- unsigned char *dstRow = dst + y * (kScreenGrabWidth * 4u);
+ unsigned char *dstRow = linearData + y * kScreenGrabWidth * 4;
const unsigned char *srcRow = src + y * mapped.RowPitch;
- std::memcpy(dstRow, srcRow, kScreenGrabWidth * 4u);
- for (unsigned int x = 0; x < kScreenGrabWidth; ++x)
- {
- dstRow[x * 4u + 3u] = 0xFF;
- }
+ memcpy(dstRow, srcRow, kScreenGrabWidth * 4);
+
+ for (UINT x = 0; x < kScreenGrabWidth; ++x)
+ dstRow[x * 4 + 3] = 0xFF;
}
+
m_pDeviceContext->Unmap(stagingTexture, 0);
}
}
@@ -556,23 +615,26 @@ void Renderer::Present()
static int count = 0;
char fileName[304];
sprintf_s(fileName, "d:\\screen%d.png", count++);
+
D3DXIMAGE_INFO info;
info.Width = kScreenGrabWidth;
info.Height = kScreenGrabHeight;
- this->SaveTextureData(fileName, &info, linearData);
+ SaveTextureData(fileName, &info, reinterpret_cast(linearData));
+
delete[] linearData;
if (stagingTexture)
{
stagingTexture->Release();
- stagingTexture = nullptr;
+ stagingTexture = NULL;
}
if (backBuffer)
{
backBuffer->Release();
- backBuffer = nullptr;
+ backBuffer = NULL;
}
- shouldScreenGrabNextFrame = 0;
+
+ m_bShouldScreenGrabNextFrame = false;
}
m_pSwapChain->Present(1, 0);
@@ -581,20 +643,23 @@ void Renderer::Present()
void Renderer::Resume()
{
- suspended = 0;
+ m_bSuspended = false;
}
void Renderer::SetClearColour(const float colourRGBA[4])
{
- std::memcpy(m_fClearColor, colourRGBA, sizeof(m_fClearColor));
+ for (int i = 0; i < 4; ++i)
+ m_fClearColor[i] = colourRGBA[i];
- Renderer::Context *c = static_cast(TlsGetValue(Renderer::tlsIdx));
- if (c)
+ Renderer::Context &c = getContext();
+ if (&c)
{
D3D11_MAPPED_SUBRESOURCE mapped = {};
- c->m_pDeviceContext->Map(c->m_clearColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- std::memcpy(mapped.pData, colourRGBA, sizeof(float) * 4);
- c->m_pDeviceContext->Unmap(c->m_clearColorBuffer, 0);
+ if (SUCCEEDED(c.m_pDeviceContext->Map(c.m_clearColorBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)))
+ {
+ *(DirectX::XMVECTOR*)mapped.pData = DirectX::XMVectorSet(colourRGBA[0], colourRGBA[1], colourRGBA[2], colourRGBA[3]);
+ c.m_pDeviceContext->Unmap(c.m_clearColorBuffer, 0);
+ }
}
}
@@ -605,71 +670,68 @@ void Renderer::SetupShaders()
vertexStrideTable = new unsigned int[C4JRender::VERTEX_TYPE_COUNT];
inputLayoutTable = new ID3D11InputLayout *[C4JRender::VERTEX_TYPE_COUNT];
- for (unsigned int i = 0; i < C4JRender::VERTEX_TYPE_COUNT; ++i)
+ for (UINT i = 0; i < C4JRender::VERTEX_TYPE_COUNT; ++i)
{
- vertexShaderTable[i] = nullptr;
- inputLayoutTable[i] = nullptr;
+ vertexShaderTable[i] = NULL;
+ inputLayoutTable[i] = NULL;
vertexStrideTable[i] = g_vertexStrides[i];
}
- for (unsigned int i = 0; i < C4JRender::PIXEL_SHADER_COUNT; ++i)
+ for (UINT i = 0; i < C4JRender::PIXEL_SHADER_COUNT; ++i)
{
- pixelShaderTable[i] = nullptr;
+ pixelShaderTable[i] = NULL;
}
- screenSpaceVertexShader = nullptr;
- screenClearVertexShader = nullptr;
- screenSpacePixelShader = nullptr;
- screenClearPixelShader = nullptr;
+ screenSpaceVertexShader = NULL;
+ screenClearVertexShader = NULL;
+ screenSpacePixelShader = NULL;
+ screenClearPixelShader = NULL;
- m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), nullptr,
- &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]);
- m_pDevice->CreateVertexShader(g_main_VS_Compressed, sizeof(g_main_VS_Compressed), nullptr, &vertexShaderTable[C4JRender::VERTEX_TYPE_COMPRESSED]);
- m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), nullptr,
- &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]);
- m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), nullptr,
- &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]);
- m_pDevice->CreateVertexShader(g_main_VS_ScreenSpace, sizeof(g_main_VS_ScreenSpace), nullptr, &screenSpaceVertexShader);
- m_pDevice->CreateVertexShader(g_main_VS_ScreenClear, sizeof(g_main_VS_ScreenClear), nullptr, &screenClearVertexShader);
+ m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]);
+ m_pDevice->CreateVertexShader(g_main_VS_Compressed, sizeof(g_main_VS_Compressed), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_COMPRESSED]);
+ m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]);
+ m_pDevice->CreateVertexShader(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), NULL, &vertexShaderTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]);
+ m_pDevice->CreateVertexShader(g_main_VS_ScreenSpace, sizeof(g_main_VS_ScreenSpace), NULL, &screenSpaceVertexShader);
+ m_pDevice->CreateVertexShader(g_main_VS_ScreenClear, sizeof(g_main_VS_ScreenClear), NULL, &screenClearVertexShader);
- m_pDevice->CreatePixelShader(g_main_PS_Standard, sizeof(g_main_PS_Standard), nullptr, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_STANDARD]);
- m_pDevice->CreatePixelShader(g_main_PS_TextureProjection, sizeof(g_main_PS_TextureProjection), nullptr,
- &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_PROJECTION]);
- m_pDevice->CreatePixelShader(g_main_PS_ForceLOD, sizeof(g_main_PS_ForceLOD), nullptr, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]);
- m_pDevice->CreatePixelShader(g_main_PS_ScreenSpace, sizeof(g_main_PS_ScreenSpace), nullptr, &screenSpacePixelShader);
- m_pDevice->CreatePixelShader(g_main_PS_ScreenClear, sizeof(g_main_PS_ScreenClear), nullptr, &screenClearPixelShader);
+ m_pDevice->CreatePixelShader(g_main_PS_Standard, sizeof(g_main_PS_Standard), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_STANDARD]);
+ m_pDevice->CreatePixelShader(g_main_PS_TextureProjection, sizeof(g_main_PS_TextureProjection), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_PROJECTION]);
+ m_pDevice->CreatePixelShader(g_main_PS_ForceLOD, sizeof(g_main_PS_ForceLOD), NULL, &pixelShaderTable[C4JRender::PIXEL_SHADER_TYPE_FORCELOD]);
+ m_pDevice->CreatePixelShader(g_main_PS_ScreenSpace, sizeof(g_main_PS_ScreenSpace), NULL, &screenSpacePixelShader);
+ m_pDevice->CreatePixelShader(g_main_PS_ScreenClear, sizeof(g_main_PS_ScreenClear), NULL, &screenClearPixelShader);
- m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1),
- &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]);
- m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_Compressed, 2, g_main_VS_Compressed, sizeof(g_main_VS_Compressed),
- &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]);
- m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING,
- sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]);
- m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN,
- sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]);
+ m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1]);
+ m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_Compressed, 2, g_main_VS_Compressed, sizeof(g_main_VS_Compressed), &inputLayoutTable[C4JRender::VERTEX_TYPE_COMPRESSED]);
+ m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_LIGHTING), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT]);
+ m_pDevice->CreateInputLayout(g_vertex_PTN_Elements_PF3_TF2_CB4_NB4_XW1, 5, g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN, sizeof(g_main_VS_PF3_TF2_CB4_NB4_XW1_TEXGEN), &inputLayoutTable[C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_TEXGEN]);
}
void Renderer::StartFrame()
{
- Renderer::Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::StartFrame", "StartFrame", MP_MAGENTA)
- activeVertexType = 0xFFFFFFFFu;
- activePixelType = 0xFFFFFFFFu;
+ Renderer::Context &c = getContext();
- this->TextureBindVertex(-1);
- this->TextureBind(-1);
- this->StateSetColour(1.0f, 1.0f, 1.0f, 1.0f);
- this->StateSetDepthMask(true);
- this->StateSetBlendEnable(true);
- this->StateSetBlendFunc(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA);
- this->StateSetBlendFactor(0xFFFFFFFFu);
- this->StateSetAlphaFunc(D3D11_COMPARISON_GREATER, 0.1f);
- this->StateSetDepthFunc(D3D11_COMPARISON_LESS_EQUAL);
- this->StateSetFaceCull(true);
- this->StateSetLineWidth(1.0f);
- this->StateSetWriteEnable(true, true, true, true);
- this->StateSetDepthTestEnable(false);
- this->StateSetAlphaTestEnable(true);
+ activeVertexType = -1;
+ activePixelType = -1;
+
+ TextureBindVertex(-1);
+ TextureBind(-1);
+
+ PROFILER_SCOPE("Renderer::StartFrame", "State", MP_MAGENTA)
+
+ StateSetColour(1.0f, 1.0f, 1.0f, 1.0f);
+ StateSetDepthMask(true);
+ StateSetBlendEnable(true);
+ StateSetBlendFunc(D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA);
+ StateSetBlendFactor(0xFFFFFFFF);
+ StateSetAlphaFunc(D3D11_COMPARISON_GREATER, 0.1f);
+ StateSetDepthFunc(D3D11_COMPARISON_LESS_EQUAL);
+ StateSetFaceCull(true);
+ StateSetLineWidth(1.0f);
+ StateSetWriteEnable(true, true, true, true);
+ StateSetDepthTestEnable(false);
+ StateSetAlphaTestEnable(true);
c.m_pDeviceContext->VSSetConstantBuffers(0, 10, &c.m_modelViewMatrix);
c.m_pDeviceContext->PSSetConstantBuffers(0, 6, &c.m_tintColorBuffer);
@@ -683,16 +745,20 @@ void Renderer::StartFrame()
viewport.MaxDepth = 1.0f;
c.m_pDeviceContext->RSSetViewports(1, &viewport);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
+
+ #ifdef ENABLE_PROFILING
+ MicroProfileFlip(nullptr);
+ #endif
}
void Renderer::Suspend()
{
- suspended = 1;
+ m_bSuspended = true;
}
bool Renderer::Suspended()
{
- return suspended != 0;
+ return m_bSuspended;
}
void Renderer::UpdateGamma(unsigned short) {}
@@ -704,16 +770,13 @@ Renderer::Context &Renderer::getContext()
void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
{
- Renderer::Context &c = this->getContext();
+ Renderer::Context &c = getContext();
- float left;
- float bottom;
- float right;
- float top;
- left = 0.0f;
- bottom = 0.0f;
- right = 1.0f;
- top = 1.0f;
+ float left = 0.0f;
+ float bottom = 0.0f;
+ float right = 1.0f;
+ float top = 1.0f;
+
switch (m_ViewportType)
{
case C4JRender::VIEWPORT_TYPE_SPLIT_TOP:
@@ -748,36 +811,38 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
break;
}
- float leftScaled = left * kAspectRatio;
- float rightScaled = right * kAspectRatio;
- const float viewportHeight = top - bottom;
- const float viewportScaledWidth = rightScaled - leftScaled;
+ float aspectRatio = IsWidescreen() ? (16.0f / 9.0f) : (4.0f / 3.0f);
- if (viewportHeight <= viewportScaledWidth)
+ right *= aspectRatio;
+ left *= aspectRatio;
+
+ float width = right - left;
+ float height = top - bottom;
+
+ if (height > width)
{
- const float pad = (viewportScaledWidth - viewportHeight) * 0.5f;
- leftScaled += pad;
- rightScaled -= pad;
+ float diff = (height - width) * 0.5f;
+ bottom += diff;
+ top -= diff;
}
else
{
- const float pad = (viewportHeight - viewportScaledWidth) * 0.5f;
- bottom += pad;
- top -= pad;
+ float diff = (width - height) * 0.5f;
+ left += diff;
+ right -= diff;
}
- const float sampleLeft = leftScaled / kAspectRatio;
- const float sampleWidth = (rightScaled - leftScaled) / kAspectRatio;
- const float sampleHeight = top - bottom;
+ left /= aspectRatio;
+ right /= aspectRatio;
- ID3D11BlendState *blendState = nullptr;
- ID3D11DepthStencilState *depthState = nullptr;
- ID3D11RasterizerState *rasterizerState = nullptr;
- ID3D11SamplerState *samplerState = nullptr;
- ID3D11Texture2D *stagingTexture = nullptr;
+ ID3D11BlendState *blendState = NULL;
+ ID3D11DepthStencilState *depthState = NULL;
+ ID3D11RasterizerState *rasterizerState = NULL;
+ ID3D11SamplerState *samplerState = NULL;
+ ID3D11Texture2D *stagingTexture = NULL;
D3D11_BLEND_DESC blendDesc = {};
- blendDesc.RenderTarget[0].BlendEnable = FALSE;
+ blendDesc.RenderTarget[0].BlendEnable = false;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
@@ -788,27 +853,24 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
m_pDevice->CreateBlendState(&blendDesc, &blendState);
D3D11_DEPTH_STENCIL_DESC depthDesc = {};
- depthDesc.DepthEnable = FALSE;
+ depthDesc.DepthEnable = false;
depthDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
depthDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
- depthDesc.StencilEnable = FALSE;
- depthDesc.StencilReadMask = 0xFFu;
- depthDesc.StencilWriteMask = 0xFFu;
+ depthDesc.StencilEnable = false;
+ depthDesc.StencilReadMask = 0xFF;
+ depthDesc.StencilWriteMask = 0xFF;
depthDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
depthDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
- depthDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
- depthDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
- depthDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
- depthDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ depthDesc.BackFace = depthDesc.FrontFace;
m_pDevice->CreateDepthStencilState(&depthDesc, &depthState);
D3D11_RASTERIZER_DESC rasterDesc = {};
rasterDesc.FillMode = D3D11_FILL_SOLID;
rasterDesc.CullMode = D3D11_CULL_NONE;
- rasterDesc.DepthClipEnable = TRUE;
- rasterDesc.MultisampleEnable = TRUE;
+ rasterDesc.DepthClipEnable = true;
+ rasterDesc.MultisampleEnable = true;
m_pDevice->CreateRasterizerState(&rasterDesc, &rasterizerState);
D3D11_SAMPLER_DESC samplerDesc = {};
@@ -822,14 +884,14 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
samplerDesc.MaxLOD = (std::numeric_limits::max)();
m_pDevice->CreateSamplerState(&samplerDesc, &samplerState);
- c.m_pDeviceContext->VSSetShader(screenSpaceVertexShader, nullptr, 0);
- c.m_pDeviceContext->IASetInputLayout(nullptr);
- c.m_pDeviceContext->PSSetShader(screenSpacePixelShader, nullptr, 0);
- c.m_pDeviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFFFu);
+ c.m_pDeviceContext->VSSetShader(screenSpaceVertexShader, NULL, 0);
+ c.m_pDeviceContext->IASetInputLayout(NULL);
+ c.m_pDeviceContext->PSSetShader(screenSpacePixelShader, NULL, 0);
+ c.m_pDeviceContext->OMSetBlendState(blendState, NULL, -1);
c.m_pDeviceContext->OMSetDepthStencilState(depthState, 0);
c.m_pDeviceContext->RSSetState(rasterizerState);
- for (unsigned int i = 0; i < MAX_MIP_LEVELS - 1; ++i)
+ for (UINT i = 0; i < MAX_MIP_LEVELS - 1; ++i)
{
D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0.0f;
@@ -839,7 +901,7 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
- c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetViews[i], nullptr);
+ c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetViews[i], NULL);
c.m_pDeviceContext->RSSetViewports(1, &viewport);
ID3D11ShaderResourceView *inputTexture = (i == 0) ? renderTargetShaderResourceView : renderTargetShaderResourceViews[i - 1];
@@ -849,13 +911,14 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
D3D11_MAPPED_SUBRESOURCE mapped = {};
c.m_pDeviceContext->Map(c.m_thumbnailBoundsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- float *constants = static_cast(mapped.pData);
+
+ float *constants = (float *)mapped.pData;
if (i == 0)
{
- constants[0] = sampleLeft;
+ constants[0] = left;
constants[1] = bottom;
- constants[2] = sampleWidth;
- constants[3] = sampleHeight;
+ constants[2] = right - left;
+ constants[3] = top - bottom;
}
else
{
@@ -864,73 +927,83 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
constants[2] = 1.0f;
constants[3] = 1.0f;
}
+
c.m_pDeviceContext->Unmap(c.m_thumbnailBoundsBuffer, 0);
c.m_pDeviceContext->Draw(4, 0);
}
- D3D11_TEXTURE2D_DESC desc = {};
- renderTargetTextures[MAX_MIP_LEVELS - 2]->GetDesc(&desc);
- desc.Usage = D3D11_USAGE_STAGING;
- desc.BindFlags = 0;
- desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
- desc.MiscFlags = 0;
- m_pDevice->CreateTexture2D(&desc, nullptr, &stagingTexture);
+ D3D11_TEXTURE2D_DESC texDesc = {};
+ renderTargetTextures[MAX_MIP_LEVELS - 2]->GetDesc(&texDesc);
+ texDesc.Usage = D3D11_USAGE_STAGING;
+ texDesc.BindFlags = 0;
+ texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ texDesc.MiscFlags = 0;
+ m_pDevice->CreateTexture2D(&texDesc, NULL, &stagingTexture);
+
+ const unsigned int stride = kThumbnailSize * 4;
+ unsigned char *linearData = new unsigned char[kThumbnailSize * stride];
- unsigned char *linearData = new unsigned char[kThumbnailSize * kThumbnailSize * 4u];
if (stagingTexture)
{
c.m_pDeviceContext->CopyResource(stagingTexture, renderTargetTextures[MAX_MIP_LEVELS - 2]);
+
D3D11_MAPPED_SUBRESOURCE mapped = {};
if (SUCCEEDED(c.m_pDeviceContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapped)))
{
const unsigned char *src = static_cast(mapped.pData);
unsigned char *dst = linearData;
- for (unsigned int y = 0; y < kThumbnailSize; ++y)
+
+ for (UINT y = 0; y < kThumbnailSize; ++y)
{
- std::memcpy(dst, src, kThumbnailSize * 4u);
- for (unsigned int x = 0; x < kThumbnailSize; ++x)
+ memcpy(dst, src, stride);
+
+ unsigned char *alpha = dst + 3;
+ for (UINT x = 0; x < kThumbnailSize; ++x)
{
- dst[x * 4u + 3u] = 0xFF;
+ *alpha = 0xFF;
+ alpha += 4;
}
+
src += mapped.RowPitch;
- dst += kThumbnailSize * 4u;
+ dst += stride;
}
+
c.m_pDeviceContext->Unmap(stagingTexture, 0);
}
}
- this->ConvertLinearToPng(pngOut, linearData, kThumbnailSize, kThumbnailSize);
+ ConvertLinearToPng(pngOut, linearData, kThumbnailSize, kThumbnailSize);
delete[] linearData;
if (stagingTexture)
{
stagingTexture->Release();
- stagingTexture = nullptr;
+ stagingTexture = NULL;
}
if (samplerState)
{
samplerState->Release();
- samplerState = nullptr;
+ samplerState = NULL;
}
if (rasterizerState)
{
rasterizerState->Release();
- rasterizerState = nullptr;
+ rasterizerState = NULL;
}
if (depthState)
{
depthState->Release();
- depthState = nullptr;
+ depthState = NULL;
}
if (blendState)
{
blendState->Release();
- blendState = nullptr;
+ blendState = NULL;
}
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
- c.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0);
- c.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState());
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, -1);
+ c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
+ c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0.0f;
@@ -939,8 +1012,10 @@ void Renderer::CaptureThumbnail(ImageFileBuffer *pngOut)
viewport.Height = (float)backBufferHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
+
c.m_pDeviceContext->RSSetViewports(1, &viewport);
c.m_pDeviceContext->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
- activeVertexType = 0xFFFFFFFFu;
- activePixelType = 0xFFFFFFFFu;
+
+ activeVertexType = -1;
+ activePixelType = -1;
}
diff --git a/Windows_Libs/Dev/Render/RendererMatrix.cpp b/Windows_Libs/Dev/Render/RendererMatrix.cpp
index fbd7c53..b33c142 100644
--- a/Windows_Libs/Dev/Render/RendererMatrix.cpp
+++ b/Windows_Libs/Dev/Render/RendererMatrix.cpp
@@ -1,18 +1,18 @@
-#pragma once
+#include "stdafx.h"
#include "Renderer.h"
#include
const float *Renderer::MatrixGet(int type)
{
- Context &c = this->getContext();
+ Context &c = getContext();
const int depth = c.stackPos[type];
return reinterpret_cast(&c.matrixStacks[type][depth]);
}
void Renderer::MatrixMode(int type)
{
- Context &c = this->getContext();
+ Context &c = getContext();
assert(type >= 0);
assert(type < STACK_TYPES);
c.stackType = type;
@@ -22,25 +22,25 @@ void Renderer::MatrixMult(float *mat)
{
DirectX::XMMATRIX matrix;
std::memcpy(&matrix, mat, sizeof(matrix));
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MatrixOrthogonal(float left, float right, float bottom, float top, float zNear, float zFar)
{
const DirectX::XMMATRIX matrix = DirectX::XMMatrixOrthographicOffCenterRH(left, right, bottom, top, zNear, zFar);
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MatrixPerspective(float fovy, float aspect, float zNear, float zFar)
{
const float fovRadians = fovy * (3.14159274f / 180.0f);
const DirectX::XMMATRIX matrix = DirectX::XMMatrixPerspectiveFovRH(fovRadians, aspect, zNear, zFar);
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MatrixPop()
{
- Context &c = this->getContext();
+ Context &c = getContext();
assert(c.stackPos[c.stackType] > 0);
@@ -51,7 +51,7 @@ void Renderer::MatrixPop()
void Renderer::MatrixPush()
{
- Context &c = this->getContext();
+ Context &c = getContext();
assert(c.stackPos[c.stackType] < (STACK_SIZE - 1));
@@ -65,18 +65,18 @@ void Renderer::MatrixRotate(float angle, float x, float y, float z)
{
const DirectX::XMVECTOR axis = DirectX::XMVectorSet(x, y, z, 0.0f);
const DirectX::XMMATRIX matrix = DirectX::XMMatrixRotationAxis(axis, angle);
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MatrixScale(float x, float y, float z)
{
const DirectX::XMMATRIX matrix = DirectX::XMMatrixScaling(x, y, z);
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MatrixSetIdentity()
{
- Context &c = this->getContext();
+ Context &c = getContext();
const int mode = c.stackType;
const int depth = c.stackPos[mode];
c.matrixStacks[mode][depth] = DirectX::XMMatrixIdentity();
@@ -86,12 +86,12 @@ void Renderer::MatrixSetIdentity()
void Renderer::MatrixTranslate(float x, float y, float z)
{
const DirectX::XMMATRIX matrix = DirectX::XMMatrixTranslation(x, y, z);
- this->MultWithStack(matrix);
+ MultWithStack(matrix);
}
void Renderer::MultWithStack(DirectX::XMMATRIX matrix)
{
- Context &c = this->getContext();
+ Context &c = getContext();
const int mode = c.stackType;
const int depth = c.stackPos[mode];
DirectX::XMMATRIX ¤t = c.matrixStacks[mode][depth];
@@ -101,7 +101,7 @@ void Renderer::MultWithStack(DirectX::XMMATRIX matrix)
void Renderer::Set_matrixDirty()
{
- Context &c = this->getContext();
+ Context &c = getContext();
const DirectX::XMMATRIX identity = DirectX::XMMatrixIdentity();
c.matrixStacks[MATRIX_MODE_MODELVIEW][0] = identity;
@@ -114,6 +114,6 @@ void Renderer::Set_matrixDirty()
c.matrixDirty[MATRIX_MODE_MODELVIEW_TEXTURE] = true;
c.matrixDirty[MATRIX_MODE_MODELVIEW_CBUFF] = true;
- activeVertexType = 0xFFFFFFFFu;
- activePixelType = 0xFFFFFFFFu;
+ activeVertexType = -1;
+ activePixelType = -1;
}
diff --git a/Windows_Libs/Dev/Render/RendererState.cpp b/Windows_Libs/Dev/Render/RendererState.cpp
index 70e9bfe..3cef1a0 100644
--- a/Windows_Libs/Dev/Render/RendererState.cpp
+++ b/Windows_Libs/Dev/Render/RendererState.cpp
@@ -1,13 +1,13 @@
-#pragma once
+#include "stdafx.h"
#include "Renderer.h"
-#include
#include
#include
ID3D11BlendState *Renderer::GetManagedBlendState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedBlendState", MP_ORCHID1)
+ Context &c = getContext();
const D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = c.blendDesc.RenderTarget[0];
const int key = (rtBlend.BlendEnable ? 1 : 0) | ((static_cast(rtBlend.SrcBlend) & 0x1F) << 1) |
@@ -15,11 +15,9 @@ ID3D11BlendState *Renderer::GetManagedBlendState()
auto it = managedBlendStates.find(key);
if (it != managedBlendStates.end())
- {
return it->second;
- }
- ID3D11BlendState *state = nullptr;
+ ID3D11BlendState *state = NULL;
m_pDevice->CreateBlendState(&c.blendDesc, &state);
managedBlendStates.emplace(key, state);
return state;
@@ -27,18 +25,17 @@ ID3D11BlendState *Renderer::GetManagedBlendState()
ID3D11DepthStencilState *Renderer::GetManagedDepthStencilState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::GetManagedBlendState", "GetManagedDepthStencilState", MP_ORCHID1)
+ Context &c = getContext();
const int key = (c.depthStencilDesc.DepthEnable ? 2 : 0) | ((static_cast(c.depthStencilDesc.DepthFunc) & 0x0F) << 2) |
(c.depthStencilDesc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL ? 1 : 0);
auto it = managedDepthStencilStates.find(key);
if (it != managedDepthStencilStates.end())
- {
return it->second;
- }
- ID3D11DepthStencilState *state = nullptr;
+ ID3D11DepthStencilState *state = NULL;
m_pDevice->CreateDepthStencilState(&c.depthStencilDesc, &state);
managedDepthStencilStates.emplace(key, state);
return state;
@@ -46,7 +43,8 @@ ID3D11DepthStencilState *Renderer::GetManagedDepthStencilState()
ID3D11RasterizerState *Renderer::GetManagedRasterizerState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::GetManagedRasterizerState", "GetManagedRasterizerState", MP_ORCHID1)
+ Context &c = getContext();
const int key = (static_cast(c.rasterizerDesc.DepthBias)) |
(static_cast(static_cast(c.rasterizerDesc.SlopeScaledDepthBias)) << 8) |
@@ -54,11 +52,9 @@ ID3D11RasterizerState *Renderer::GetManagedRasterizerState()
auto it = managedRasterizerStates.find(key);
if (it != managedRasterizerStates.end())
- {
return it->second;
- }
- ID3D11RasterizerState *state = nullptr;
+ ID3D11RasterizerState *state = NULL;
m_pDevice->CreateRasterizerState(&c.rasterizerDesc, &state);
managedRasterizerStates.emplace(key, state);
return state;
@@ -66,14 +62,13 @@ ID3D11RasterizerState *Renderer::GetManagedRasterizerState()
ID3D11SamplerState *Renderer::GetManagedSamplerState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::GetManagedSamplerState", "GetManagedSamplerState", MP_ORCHID1)
+ Context &c = getContext();
const int key = m_textures[c.textureIdx].samplerParams;
auto it = managedSamplerStates.find(key);
if (it != managedSamplerStates.end())
- {
return it->second;
- }
const bool clampU = (key & 0x01) != 0;
const bool clampV = (key & 0x02) != 0;
@@ -96,7 +91,7 @@ ID3D11SamplerState *Renderer::GetManagedSamplerState()
desc.MinLOD = -(std::numeric_limits::max)();
desc.MaxLOD = (std::numeric_limits::max)();
- ID3D11SamplerState *state = nullptr;
+ ID3D11SamplerState *state = NULL;
m_pDevice->CreateSamplerState(&desc, &state);
managedSamplerStates.emplace(key, state);
return state;
@@ -104,37 +99,37 @@ ID3D11SamplerState *Renderer::GetManagedSamplerState()
void Renderer::StateSetFogEnable(bool enable)
{
- Context &c = this->getContext();
- c.fogEnabled = enable ? 1 : 0;
+ Context &c = getContext();
+ c.fogEnabled = enable;
}
void Renderer::StateSetFogMode(int mode)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.fogMode = mode;
}
void Renderer::StateSetFogNearDistance(float dist)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.fogNearDistance = dist;
}
void Renderer::StateSetFogFarDistance(float dist)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.fogFarDistance = dist;
}
void Renderer::StateSetFogDensity(float density)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.fogDensity = density;
}
void Renderer::StateSetFogColour(float red, float green, float blue)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.fogColourRed = red;
c.fogColourBlue = blue;
c.fogColourGreen = green;
@@ -144,25 +139,23 @@ void Renderer::UpdateViewportState() {}
void Renderer::StateSetLightingEnable(bool enable)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetLightingEnable(enable);
return;
}
- c.lightingEnabled = enable ? 1 : 0;
+ c.lightingEnabled = enable;
}
void Renderer::StateSetLightColour(int light, float red, float green, float blue)
{
if (light >= 2)
- {
return;
- }
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetLightColour(light, red, green, blue);
return;
@@ -172,13 +165,13 @@ void Renderer::StateSetLightColour(int light, float red, float green, float blue
c.lightColour[light].y = green;
c.lightColour[light].z = blue;
c.lightColour[light].w = 1.0f;
- c.lightingDirty = 1;
+ c.lightingDirty = true;
}
void Renderer::StateSetLightAmbientColour(float red, float green, float blue)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetLightAmbientColour(red, green, blue);
return;
@@ -188,31 +181,29 @@ void Renderer::StateSetLightAmbientColour(float red, float green, float blue)
c.lightAmbientColour.y = green;
c.lightAmbientColour.z = blue;
c.lightAmbientColour.w = 1.0f;
- c.lightingDirty = 1;
+ c.lightingDirty = true;
}
void Renderer::StateSetLightEnable(int light, bool enable)
{
if (light >= 2)
- {
return;
- }
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetLightEnable(light, enable);
return;
}
- c.lightEnabled[light] = enable ? 1 : 0;
- c.lightingDirty = 1;
+ c.lightEnabled[light] = enable;
+ c.lightingDirty = true;
}
void Renderer::StateSetColour(float r, float g, float b, float a)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetColor(r, g, b, a);
return;
@@ -229,35 +220,35 @@ void Renderer::StateSetColour(float r, float g, float b, float a)
void Renderer::StateSetDepthMask(bool enable)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetDepthMask(enable);
return;
}
c.depthStencilDesc.DepthWriteMask = enable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
- c.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0);
- c.depthWriteEnabled = enable ? 1 : 0;
+ c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
+ c.depthWriteEnabled = enable;
}
void Renderer::StateSetBlendEnable(bool enable)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetBlendEnable(enable);
return;
}
- c.blendDesc.RenderTarget[0].BlendEnable = enable ? TRUE : FALSE;
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.blendDesc.RenderTarget[0].BlendEnable = enable;
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
}
void Renderer::StateSetBlendFunc(int src, int dst)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetBlendFunc(src, dst);
return;
@@ -265,29 +256,29 @@ void Renderer::StateSetBlendFunc(int src, int dst)
c.blendDesc.RenderTarget[0].SrcBlend = static_cast(src);
c.blendDesc.RenderTarget[0].DestBlend = static_cast(dst);
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
}
void Renderer::StateSetBlendFactor(unsigned int colour)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetBlendFactor(colour);
return;
}
const float scale = 255.0f;
- c.blendFactor[0] = static_cast((colour >> 0) & 0xFFu) / scale;
- c.blendFactor[1] = static_cast((colour >> 8) & 0xFFu) / scale;
- c.blendFactor[2] = static_cast((colour >> 16) & 0xFFu) / scale;
- c.blendFactor[3] = static_cast((colour >> 24) & 0xFFu) / scale;
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.blendFactor[0] = static_cast((colour >> 0) & 0xFF) / scale;
+ c.blendFactor[1] = static_cast((colour >> 8) & 0xFF) / scale;
+ c.blendFactor[2] = static_cast((colour >> 16) & 0xFF) / scale;
+ c.blendFactor[3] = static_cast((colour >> 24) & 0xFF) / scale;
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
}
void Renderer::StateSetAlphaFunc(int, float param)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.alphaReference = param;
const float alpha[4] = {0.0f, 0.0f, 0.0f, c.alphaTestEnabled ? c.alphaReference : 0.0f};
@@ -299,51 +290,47 @@ void Renderer::StateSetAlphaFunc(int, float param)
void Renderer::StateSetDepthFunc(int func)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetDepthFunc(func);
return;
}
c.depthStencilDesc.DepthFunc = static_cast(func);
- c.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0);
+ c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
}
void Renderer::StateSetFaceCull(bool enable)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetFaceCull(enable);
return;
}
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
- c.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState());
- c.faceCullEnabled = enable ? 1 : 0;
+ c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
+ c.faceCullEnabled = enable;
}
void Renderer::StateSetFaceCullCW(bool enable)
{
- Context &c = this->getContext();
+ Context &c = getContext();
if (c.faceCullEnabled)
- {
c.rasterizerDesc.CullMode = enable ? D3D11_CULL_BACK : D3D11_CULL_FRONT;
- }
else
- {
c.rasterizerDesc.CullMode = D3D11_CULL_NONE;
- }
- c.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState());
+ c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
}
void Renderer::StateSetLineWidth(float) {}
void Renderer::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha)
{
- Context &c = this->getContext();
+ Context &c = getContext();
std::uint8_t mask = 0;
mask |= red ? 0x1 : 0;
@@ -352,27 +339,27 @@ void Renderer::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha)
mask |= alpha ? 0x8 : 0;
c.blendDesc.RenderTarget[0].RenderTargetWriteMask = mask;
- c.m_pDeviceContext->OMSetBlendState(this->GetManagedBlendState(), c.blendFactor, 0xFFFFFFFFu);
+ c.m_pDeviceContext->OMSetBlendState(GetManagedBlendState(), c.blendFactor, 0xFFFFFFFF);
}
void Renderer::StateSetDepthTestEnable(bool enable)
{
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetDepthTestEnable(enable);
return;
}
- c.depthStencilDesc.DepthEnable = enable ? TRUE : FALSE;
- c.m_pDeviceContext->OMSetDepthStencilState(this->GetManagedDepthStencilState(), 0);
- c.depthTestEnabled = enable ? 1 : 0;
+ c.depthStencilDesc.DepthEnable = enable;
+ c.m_pDeviceContext->OMSetDepthStencilState(GetManagedDepthStencilState(), 0);
+ c.depthTestEnabled = enable;
}
void Renderer::StateSetAlphaTestEnable(bool enable)
{
- Context &c = this->getContext();
- c.alphaTestEnabled = enable ? 1 : 0;
+ Context &c = getContext();
+ c.alphaTestEnabled = enable;
const float alpha[4] = {0.0f, 0.0f, 0.0f, enable ? c.alphaReference : 0.0f};
D3D11_MAPPED_SUBRESOURCE mapped = {};
@@ -383,17 +370,18 @@ void Renderer::StateSetAlphaTestEnable(bool enable)
void Renderer::StateSetDepthSlopeAndBias(float slope, float bias)
{
- Context &c = this->getContext();
+ Context &c = getContext();
const float scale = 65536.0f;
c.rasterizerDesc.DepthBias = static_cast(bias * scale);
c.rasterizerDesc.SlopeScaledDepthBias = slope * scale;
- c.m_pDeviceContext->RSSetState(this->GetManagedRasterizerState());
+ c.m_pDeviceContext->RSSetState(GetManagedRasterizerState());
}
void Renderer::UpdateFogState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::UpdateFogState", "UpdateFogState", MP_ORCHID1)
+ Context &c = getContext();
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
float fogParams[4] = {};
@@ -426,7 +414,7 @@ void Renderer::UpdateFogState()
void Renderer::StateSetVertexTextureUV(float u, float v)
{
- Context &c = this->getContext();
+ Context &c = getContext();
const float texgen[4] = {u - 1.0f, v - 1.0f, 0.0f, 0.0f};
D3D11_MAPPED_SUBRESOURCE mapped = {};
@@ -437,7 +425,8 @@ void Renderer::StateSetVertexTextureUV(float u, float v)
void Renderer::UpdateTexGenState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::UpdateTexGenState", "UpdateTexGenState", MP_ORCHID1)
+ Context &c = getContext();
D3D11_MAPPED_SUBRESOURCE mapped = {};
c.m_pDeviceContext->Map(c.m_texGenMatricesBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
@@ -447,7 +436,8 @@ void Renderer::UpdateTexGenState()
void Renderer::UpdateLightingState()
{
- Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::UpdateLightingState", "UpdateLightingState", MP_ORCHID1)
+ Context &c = getContext();
if (!c.lightingDirty || !c.lightingEnabled)
{
return;
@@ -471,18 +461,16 @@ void Renderer::UpdateLightingState()
std::memcpy(mapped.pData, c.lightDirection, lightingBytes);
c.m_pDeviceContext->Unmap(c.m_lightingStateBuffer, 0);
- c.lightingDirty = 0;
+ c.lightingDirty = false;
}
void Renderer::StateSetLightDirection(int light, float x, float y, float z)
{
if (light >= 2)
- {
return;
- }
- Context &c = this->getContext();
- if (c.commandBuffer != nullptr && c.commandBuffer->isActive != 0)
+ Context &c = getContext();
+ if (c.commandBuffer != NULL && c.commandBuffer->isActive != 0)
{
c.commandBuffer->SetLightDirection(light, x, y, z);
return;
@@ -495,12 +483,12 @@ void Renderer::StateSetLightDirection(int light, float x, float y, float z)
const DirectX::XMVECTOR normalized = DirectX::XMVector3Normalize(transformed);
DirectX::XMStoreFloat4(&c.lightDirection[light], normalized);
- c.lightingDirty = 1;
+ c.lightingDirty = true;
}
void Renderer::StateSetViewport(C4JRender::eViewportType viewportType)
{
- this->getContext();
+ getContext();
m_ViewportType = viewportType;
const float fullWidth = static_cast(backBufferWidth);
@@ -569,14 +557,14 @@ void Renderer::StateSetEnableViewportClipPlanes(bool) {}
void Renderer::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace)
{
- Context &c = this->getContext();
+ Context &c = getContext();
DirectX::XMVECTOR plane = DirectX::XMVectorSet(x, y, z, w);
if (eyeSpace)
{
DirectX::XMFLOAT4X4 modelView;
std::memset(&modelView, 0, sizeof(modelView));
- std::memcpy(&modelView, this->MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(modelView));
+ std::memcpy(&modelView, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(modelView));
DirectX::XMVECTOR determinant = DirectX::XMVectorZero();
const DirectX::XMMATRIX inverse = DirectX::XMMatrixInverse(&determinant, DirectX::XMLoadFloat4x4(&modelView));
@@ -604,35 +592,33 @@ void Renderer::StateSetTexGenCol(int col, float x, float y, float z, float w, bo
void Renderer::StateSetStencil(D3D11_COMPARISON_FUNC function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask)
{
- Context &c = this->getContext();
+ Context &c = getContext();
D3D11_DEPTH_STENCIL_DESC desc = c.depthStencilDesc;
- desc.StencilEnable = TRUE;
+ desc.StencilEnable = true;
desc.StencilReadMask = stencil_func_mask;
desc.StencilWriteMask = stencil_write_mask;
desc.FrontFace.StencilFunc = function;
desc.BackFace.StencilFunc = function;
- ID3D11DepthStencilState *state = nullptr;
+ ID3D11DepthStencilState *state = NULL;
m_pDevice->CreateDepthStencilState(&desc, &state);
m_pDeviceContext->OMSetDepthStencilState(state, stencil_ref);
- if (state != nullptr)
- {
- state->Release();
- }
+ if (state != NULL) state->Release();
}
void Renderer::StateSetForceLOD(int LOD)
{
- Context &c = this->getContext();
+ Context &c = getContext();
c.forcedLOD = LOD;
}
void Renderer::StateUpdate()
{
- Context &c = this->getContext();
- this->StateSetFaceCull(c.faceCullEnabled != 0);
- this->StateSetDepthMask(c.depthWriteEnabled != 0);
- this->StateSetDepthTestEnable(c.depthTestEnabled != 0);
- this->StateSetAlphaTestEnable(c.alphaTestEnabled != 0);
+ PROFILER_SCOPE("Renderer::StateUpdate", "StateUpdate", MP_ORCHID1)
+ Context &c = getContext();
+ StateSetFaceCull(c.faceCullEnabled);
+ StateSetDepthMask(c.depthWriteEnabled);
+ StateSetDepthTestEnable(c.depthTestEnabled);
+ StateSetAlphaTestEnable(c.alphaTestEnabled);
}
diff --git a/Windows_Libs/Dev/Render/RendererTexture.cpp b/Windows_Libs/Dev/Render/RendererTexture.cpp
index 40c5925..f9243d9 100644
--- a/Windows_Libs/Dev/Render/RendererTexture.cpp
+++ b/Windows_Libs/Dev/Render/RendererTexture.cpp
@@ -1,372 +1,326 @@
-#pragma once
+#include "stdafx.h"
#include "Renderer.h"
#include "libpng/png.h"
-#include
-#include
-#include
-#include
+unsigned char* dataStart;
+unsigned char *dataCurr;
+unsigned char *dataEnd;
-DXGI_FORMAT Renderer::textureFormats[C4JRender::MAX_TEXTURE_FORMATS] = {
- DXGI_FORMAT_B8G8R8A8_UNORM,
-};
+DXGI_FORMAT Renderer::textureFormats[] = { DXGI_FORMAT_B8G8R8A8_UNORM };
+
+void user_write_data_init(unsigned char* pBuffer, int size)
+{
+ dataStart = pBuffer;
+ dataCurr = pBuffer;
+ dataEnd = pBuffer + size;
+}
+
+int user_write_data_bytes_written()
+{
+ return static_cast(dataCurr - dataStart);
+}
+
+void user_write_data(png_struct_def* png_ptr, unsigned char* src, size_t length)
+{
+ int bytesToWrite = static_cast(dataEnd - dataCurr);
+ if (static_cast(length) < bytesToWrite)
+ bytesToWrite = static_cast(length);
+
+ memcpy(dataCurr, src, bytesToWrite);
+ dataCurr += bytesToWrite;
+}
+
+void user_flush_data(png_struct_def* png_ptr)
+{
+ // TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
+}
int Renderer::TextureCreate()
{
- int i = 0;
- for (; ; i++)
+ PROFILER_SCOPE("Renderer::TextureCreate", "TextureCreate", MP_PURPLE4)
+ for (int i = 0; i < MAX_TEXTURES; i++)
{
- assert(i < 512);
-
if (!m_textures[i].allocated)
{
- break;
+ m_textures[i].texture = NULL;
+ m_textures[i].allocated = true;
+ m_textures[i].mipLevels = 1;
+ m_textures[i].textureFormat = 0;
+ return i;
}
}
-
- m_textures[i].texture = nullptr;
- m_textures[i].allocated = true;
- m_textures[i].mipLevels = 1;
- m_textures[i].samplerParams = 0;
- return i;
-}
-
-void Renderer::TextureSetTextureLevels(int levels)
-{
- const int textureIdx = this->getContext().textureIdx;
-
- assert(levels <= MAX_MIP_LEVELS);
-
- m_textures[textureIdx].mipLevels = levels;
-}
-
-int Renderer::TextureGetTextureLevels()
-{
- const int textureIdx = this->getContext().textureIdx;
- return m_textures[textureIdx].mipLevels;
-}
-
-void Renderer::TextureSetParam(int param, int value)
-{
- Texture &texture = m_textures[this->getContext().textureIdx];
-
- switch (param)
- {
- case GL_TEXTURE_MIN_FILTER:
- texture.samplerParams &= ~4u;
- if (value == 1)
- {
- texture.samplerParams |= 4u;
- }
- break;
- case GL_TEXTURE_MAG_FILTER:
- texture.samplerParams &= ~8u;
- if (value == 1)
- {
- texture.samplerParams |= 8u;
- }
- break;
- case GL_TEXTURE_WRAP_S:
- texture.samplerParams &= ~1u;
- if (value == 0)
- {
- texture.samplerParams |= 1u;
- }
- break;
- case GL_TEXTURE_WRAP_T:
- case 5: // GL_TEXTURE_WRAP_R, but this renderer only supports 2D textures, so treat it as GL_TEXTURE_WRAP_T
- texture.samplerParams &= ~2u;
- if (value == 0)
- {
- texture.samplerParams |= 2u;
- }
- break;
- default:
- break;
- }
-}
-
-void Renderer::TextureDynamicUpdateStart() {}
-
-void Renderer::TextureDynamicUpdateEnd() {}
-
-void Renderer::TextureData(int width, int height, void *data, int level, C4JRender::eTextureFormat format)
-{
- Renderer::Context &c = this->getContext();
-
- assert(m_textures[c.textureIdx].allocated);
- assert((level > 0) || (m_textures[c.textureIdx].texture == NULL));
-
- Texture &texture = m_textures[c.textureIdx];
- texture.textureFormat = format;
-
- if (level == 0)
- {
- D3D11_TEXTURE2D_DESC desc = {};
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = texture.mipLevels;
- desc.ArraySize = 1;
- desc.Format = textureFormats[format];
- desc.SampleDesc.Count = 1;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
-
- HRESULT hr = 0;
- hr = m_pDevice->CreateTexture2D(&desc, nullptr, &texture.texture);
- assert(hr >= 0);
-
- hr = m_pDevice->CreateShaderResourceView(texture.texture, nullptr, &texture.view);
- assert(hr >= 0);
- }
-
- const UINT rowPitch = width * 4u;
- const UINT depthPitch = width * height * 4u;
- c.m_pDeviceContext->UpdateSubresource(texture.texture, level, nullptr, data, rowPitch, depthPitch);
-}
-
-void Renderer::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void *data, int level)
-{
- Renderer::Context &c = this->getContext();
- Texture &texture = m_textures[c.textureIdx];
-
- D3D11_BOX box = {};
- box.left = xoffset;
- box.right = xoffset + width;
- box.top = yoffset;
- box.bottom = yoffset + height;
- box.front = 0;
- box.back = 1;
-
- D3D11_TEXTURE2D_DESC desc = {};
- texture.texture->GetDesc(&desc);
-
- const UINT rowPitch = width * 4u;
- const UINT depthPitch = width * height * 4u;
- c.m_pDeviceContext->UpdateSubresource(texture.texture, level, &box, data, rowPitch, depthPitch);
+ return -1;
}
void Renderer::TextureFree(int idx)
{
- Texture &texture = m_textures[idx];
- texture.texture->Release();
- texture.view->Release();
- texture.view = nullptr;
- texture.allocated = false;
- texture.texture = nullptr;
-}
-
-void Renderer::TextureGetStats() {}
-
-ID3D11ShaderResourceView *Renderer::TextureGetTexture(int idx)
-{
- if (idx < 0 || idx > 0x1FF)
+ PROFILER_SCOPE("Renderer::TextureFree", "TextureFree", MP_PURPLE4)
+ if (m_textures[idx].texture)
{
- return nullptr;
+ m_textures[idx].texture->Release();
+ m_textures[idx].texture = NULL;
}
-
- const Texture &texture = m_textures[idx];
- if (!texture.allocated)
+ if (m_textures[idx].view)
{
- return nullptr;
+ m_textures[idx].view->Release();
+ m_textures[idx].view = NULL;
}
-
- return texture.view;
+ m_textures[idx].allocated = false;
}
void Renderer::TextureBind(int idx)
{
- int textureIndex = idx;
- if (textureIndex == -1)
- {
- textureIndex = defaultTextureIndex;
- }
+ PROFILER_SCOPE("Renderer::TextureBind", "TextureBind", MP_PURPLE4)
+ if (idx == -1)
+ idx = defaultTextureIndex;
- Renderer::Context &c = this->getContext();
+ Context& c = getContext();
if (c.commandBuffer && c.commandBuffer->isActive)
- {
- c.commandBuffer->BindTexture(textureIndex);
- }
+ c.commandBuffer->BindTexture(idx);
- c.textureIdx = textureIndex;
- ID3D11ShaderResourceView *const view = m_textures[textureIndex].view;
- c.m_pDeviceContext->PSSetShaderResources(0, 1, &view);
- this->UpdateTextureState(false);
+ c.textureIdx = idx;
+ c.m_pDeviceContext->PSSetShaderResources(0, 1, &m_textures[idx].view);
+
+ UpdateTextureState(false);
}
void Renderer::TextureBindVertex(int idx)
{
- int textureIndex = idx;
- if (textureIndex == -1)
- {
- textureIndex = defaultTextureIndex;
- }
+ PROFILER_SCOPE("Renderer::TextureBindVertex", "TextureBindVertex", MP_PURPLE4)
+ if (idx == -1)
+ idx = defaultTextureIndex;
- Renderer::Context &c = this->getContext();
- c.textureIdx = textureIndex;
+ Context& c = getContext();
- ID3D11ShaderResourceView *const view = m_textures[textureIndex].view;
- c.m_pDeviceContext->VSSetShaderResources(0, 1, &view);
- this->UpdateTextureState(true);
+ c.textureIdx = idx;
+ c.m_pDeviceContext->VSSetShaderResources(0, 1, &m_textures[idx].view);
+
+ UpdateTextureState(true);
}
-void Renderer::UpdateTextureState(bool vertexSampler)
+void Renderer::TextureSetTextureLevels(int levels)
{
- Renderer::Context &c = this->getContext();
- ID3D11SamplerState *sampler = this->GetManagedSamplerState();
+ Context& c = getContext();
+ m_textures[c.textureIdx].mipLevels = levels;
+}
- if (vertexSampler)
+int Renderer::TextureGetTextureLevels()
+{
+ Context& c = getContext();
+ return m_textures[c.textureIdx].mipLevels;
+}
+
+void Renderer::TextureData(int width, int height, void* data, int level, C4JRender::eTextureFormat format)
+{
+ PROFILER_SCOPE("Renderer::TextureData", "TextureData", MP_PURPLE4)
+ Context& c = getContext();
+ int idx = c.textureIdx;
+
+ m_textures[idx].textureFormat = format;
+
+ if (level == 0)
{
- c.m_pDeviceContext->VSSetSamplers(0, 1, &sampler);
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = m_textures[idx].mipLevels;
+ desc.ArraySize = 1;
+ desc.Format = textureFormats[format];
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ m_pDevice->CreateTexture2D(&desc, NULL, &m_textures[idx].texture);
+ m_pDevice->CreateShaderResourceView(m_textures[idx].texture, NULL, &m_textures[idx].view);
}
+
+ c.m_pDeviceContext->UpdateSubresource(
+ m_textures[idx].texture,
+ level,
+ NULL,
+ data,
+ static_cast(width * 4),
+ static_cast(width * height * 4)
+ );
+}
+
+void Renderer::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void* data, int level)
+{
+ PROFILER_SCOPE("Renderer::TextureDataUpdate", "TextureDataUpdate", MP_PURPLE4)
+ Context& c = getContext();
+ int idx = c.textureIdx;
+
+ D3D11_TEXTURE2D_DESC desc;
+ m_textures[idx].texture->GetDesc(&desc);
+
+ D3D11_BOX box;
+ box.left = xoffset;
+ box.top = yoffset;
+ box.right = xoffset + width;
+ box.bottom = yoffset + height;
+ box.front = 0;
+ box.back = 1;
+
+ c.m_pDeviceContext->UpdateSubresource(
+ m_textures[idx].texture,
+ level,
+ &box,
+ data,
+ static_cast(width * 4),
+ static_cast(width * height * 4)
+ );
+}
+
+void Renderer::TextureSetParam(int param, int value)
+{
+ Context& c = getContext();
+ int idx = c.textureIdx;
+
+ switch (param)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ m_textures[idx].samplerParams &= ~4u;
+ if (value == GL_LINEAR)
+ m_textures[idx].samplerParams |= 4u;
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ m_textures[idx].samplerParams &= ~8u;
+ if (value == GL_LINEAR)
+ m_textures[idx].samplerParams |= 8u;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ m_textures[idx].samplerParams &= ~1u;
+ if (value == GL_CLAMP)
+ m_textures[idx].samplerParams |= 1u;
+ break;
+ case GL_TEXTURE_WRAP_T:
+ m_textures[idx].samplerParams &= ~2u;
+ if (value == GL_CLAMP)
+ m_textures[idx].samplerParams |= 2u;
+ break;
+ }
+}
+
+void Renderer::TextureDynamicUpdateStart()
+{
+ // TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
+}
+
+void Renderer::TextureDynamicUpdateEnd()
+{
+ // TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
+}
+
+void Renderer::UpdateTextureState(bool bVertex)
+{
+ Context& c = getContext();
+ ID3D11SamplerState* pSampler = GetManagedSamplerState();
+
+ if (bVertex)
+ c.m_pDeviceContext->VSSetSamplers(0, 1, &pSampler);
else
- {
- c.m_pDeviceContext->PSSetSamplers(0, 1, &sampler);
- }
+ c.m_pDeviceContext->PSSetSamplers(0, 1, &pSampler);
}
-HRESULT Renderer::LoadTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut)
+HRESULT Renderer::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
{
- if (!szFilename || !pSrcInfo || !ppDataOut)
- {
- return -1;
- }
-
- *ppDataOut = nullptr;
-
+ PROFILER_SCOPE("Renderer::LoadTextureData_File", "LoadTextureData_File", MP_PURPLE4)
png_image image;
- std::memset(&image, 0, sizeof(image));
+ memset(&image, 0, sizeof(image));
image.version = PNG_IMAGE_VERSION;
+
if (!png_image_begin_read_from_file(&image, szFilename))
- {
return -1;
- }
- if (image.width == 0 || image.height == 0)
- {
- png_image_free(&image);
- return -1;
- }
+ // TODO(3UR): why crash?
+ //if ((image.format & 3u) > 1)
+ // return -1;
image.format = PNG_FORMAT_RGBA;
- const png_alloc_size_t pixelCount = png_alloc_size_t(image.width) * png_alloc_size_t(image.height);
- if (pixelCount == 0 || pixelCount > (std::numeric_limits::max)() / sizeof(int))
- {
- png_image_free(&image);
+
+ *ppDataOut = new int[image.width * image.height];
+ if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, 0, NULL))
return -1;
- }
- int *output = new (std::nothrow) int[size_t(pixelCount)];
-
- if (!output)
- {
- png_image_free(&image);
- return -1;
- }
-
- if (!png_image_finish_read(&image, nullptr, output, 0, nullptr))
- {
- delete[] output;
- png_image_free(&image);
- return -1;
- }
-
- *ppDataOut = output;
pSrcInfo->Width = image.width;
pSrcInfo->Height = image.height;
- png_image_free(&image);
- return 0;
+ return S_OK;
}
-HRESULT Renderer::LoadTextureData(BYTE *pbData, DWORD dwBytes, D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut)
+HRESULT Renderer::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
{
- if (!pbData || dwBytes == 0 || !pSrcInfo || !ppDataOut)
- {
- return -1;
- }
-
- *ppDataOut = nullptr;
-
+ PROFILER_SCOPE("Renderer::LoadTextureData_Memory", "LoadTextureData_Memory", MP_PURPLE4)
png_image image;
- std::memset(&image, 0, sizeof(image));
+ memset(&image, 0, sizeof(image));
image.version = PNG_IMAGE_VERSION;
- if (!png_image_begin_read_from_memory(&image, pbData, dwBytes))
- {
- return -1;
- }
- if (image.width == 0 || image.height == 0)
- {
- png_image_free(&image);
+ if (!png_image_begin_read_from_memory(&image, pbData, dwBytes))
return -1;
- }
+
+ // TODO(3UR): why crash?
+ //if ((image.format & 3u) > 1)
+ // return -1;
image.format = PNG_FORMAT_RGBA;
- const png_alloc_size_t pixelCount = png_alloc_size_t(image.width) * png_alloc_size_t(image.height);
- if (pixelCount == 0 || pixelCount > (std::numeric_limits::max)() / sizeof(int))
- {
- png_image_free(&image);
+
+ *ppDataOut = new int[image.width * image.height];
+ if (!*ppDataOut || !png_image_finish_read(&image, NULL, *ppDataOut, 0, NULL))
return -1;
- }
- int *output = new (std::nothrow) int[size_t(pixelCount)];
-
- if (!output)
- {
- png_image_free(&image);
- return -1;
- }
-
- if (!png_image_finish_read(&image, nullptr, output, 0, nullptr))
- {
- delete[] output;
- png_image_free(&image);
- return -1;
- }
-
- *ppDataOut = output;
pSrcInfo->Width = image.width;
pSrcInfo->Height = image.height;
- png_image_free(&image);
- return 0;
+ return S_OK;
}
-HRESULT Renderer::SaveTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcInfo, int *ppDataOut)
+HRESULT Renderer::SaveTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int* ppDataOut)
{
- png_image image = {};
- image.version = PNG_IMAGE_VERSION;
+ PROFILER_SCOPE("Renderer::SaveTextureData", "SaveTextureData", MP_PURPLE4)
+ png_image image;
+ memset(&image, 0, sizeof(image));
image.width = pSrcInfo->Width;
image.height = pSrcInfo->Height;
+ image.version = PNG_IMAGE_VERSION;
image.format = PNG_FORMAT_RGBA;
- png_image_write_to_file(&image, szFilename, 0, ppDataOut, 0, nullptr);
- return 0;
+ png_image_write_to_file(&image, szFilename, 0, ppDataOut, 0, NULL);
+ return S_OK;
}
-HRESULT Renderer::SaveTextureDataToMemory(void *pOutput, int outputCapacity, int *outputLength, int width, int height, int *ppDataIn)
+HRESULT Renderer::SaveTextureDataToMemory(void* pOutput, int outputCapacity, int* outputLength, int width, int height, int* ppDataIn)
{
- if (!pOutput || outputCapacity <= 0 || !outputLength || width <= 0 || height <= 0 || !ppDataIn)
- {
- return -1;
- }
-
+ PROFILER_SCOPE("Renderer::SaveTextureDataToMemory", "SaveTextureDataToMemory", MP_PURPLE4)
png_image image;
- std::memset(&image, 0, sizeof(image));
- image.version = PNG_IMAGE_VERSION;
+ memset(&image, 0, sizeof(image));
image.width = width;
image.height = height;
+ image.version = PNG_IMAGE_VERSION;
image.format = PNG_FORMAT_RGBA;
- png_alloc_size_t memoryBytes = static_cast(outputCapacity);
- if (!png_image_write_to_memory(&image, pOutput, &memoryBytes, 0, ppDataIn, 0, nullptr))
- {
- *outputLength = 0;
- png_image_free(&image);
- return -1;
- }
+ dataEnd = (BYTE*)pOutput + outputCapacity;
+ dataStart = (BYTE*)pOutput;
+ dataCurr = (BYTE*)pOutput;
- *outputLength = static_cast(memoryBytes);
- png_image_free(&image);
- return 0;
+ png_image_write_to_stdio(&image, NULL, 0, ppDataIn, 0, NULL, user_write_data, user_flush_data);
+
+ *outputLength = static_cast(dataCurr - dataStart);
+ return S_OK;
}
+
+void Renderer::TextureGetStats()
+{
+ // TODO(3UR): this is for a different platform? it's empty in Render_PC.lib but not Render.lib
+}
+
+ID3D11ShaderResourceView* Renderer::TextureGetTexture(int idx)
+{
+ if ((unsigned int)idx <= 511)
+ {
+ if (m_textures[idx].allocated)
+ return m_textures[idx].view;
+ }
+ return NULL;
+}
\ No newline at end of file
diff --git a/Windows_Libs/Dev/Render/RendererVertex.cpp b/Windows_Libs/Dev/Render/RendererVertex.cpp
index 4fbb93d..ff806ec 100644
--- a/Windows_Libs/Dev/Render/RendererVertex.cpp
+++ b/Windows_Libs/Dev/Render/RendererVertex.cpp
@@ -1,59 +1,51 @@
-#pragma once
+#include "stdafx.h"
#include "Renderer.h"
-#include
-#include
-#include
-
-D3D11_PRIMITIVE_TOPOLOGY *Renderer::m_Topologies = nullptr;
-
void Renderer::DrawVertexBuffer(C4JRender::ePrimitiveType PrimitiveType, int count, ID3D11Buffer *buffer, C4JRender::eVertexType vType,
C4JRender::ePixelShaderType psType)
{
- Renderer::Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexBuffer", MP_RED2)
+ Renderer::Context &c = getContext();
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
int drawCount = count;
bool indexed = false;
- this->DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
- this->StateUpdate();
+
+ PROFILER_SCOPE("Renderer::DrawVertexBuffer", "DrawVertexSetup", MP_RED2)
+ DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
+ StateUpdate();
const UINT stride = vertexStrideTable[vType];
const UINT offset = 0;
d3d11->IASetVertexBuffers(0, 1, &buffer, &stride, &offset);
if (indexed)
- {
d3d11->DrawIndexed(drawCount, 0, 0);
- }
else
- {
d3d11->Draw(count, 0);
- }
}
void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelShaderType psType, C4JRender::ePrimitiveType PrimitiveType, int *count,
bool *indexed)
{
- Renderer::Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::DrawVertexSetup", "DrawVertexSetup", MP_RED2)
+ Renderer::Context &c = getContext();
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
C4JRender::eVertexType effectiveVertexType = vType;
if (effectiveVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1 && c.lightingEnabled)
- {
effectiveVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
- }
if (effectiveVertexType != activeVertexType)
{
- d3d11->VSSetShader(vertexShaderTable[effectiveVertexType], nullptr, 0);
+ d3d11->VSSetShader(vertexShaderTable[effectiveVertexType], NULL, 0);
d3d11->IASetInputLayout(inputLayoutTable[effectiveVertexType]);
activeVertexType = effectiveVertexType;
}
if (psType != activePixelType)
{
- d3d11->PSSetShader(pixelShaderTable[psType], nullptr, 0);
+ d3d11->PSSetShader(pixelShaderTable[psType], NULL, 0);
activePixelType = psType;
}
@@ -62,7 +54,7 @@ void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelSh
if (c.matrixDirty[MATRIX_MODE_MODELVIEW])
{
d3d11->Map(c.m_modelViewMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- std::memcpy(mapped.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
+ memcpy(mapped.pData, MatrixGet(MATRIX_MODE_MODELVIEW), sizeof(DirectX::XMMATRIX));
d3d11->Unmap(c.m_modelViewMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW] = false;
}
@@ -70,7 +62,7 @@ void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelSh
if (c.matrixDirty[MATRIX_MODE_MODELVIEW_PROJECTION])
{
d3d11->Map(c.m_projectionMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- std::memcpy(mapped.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
+ memcpy(mapped.pData, MatrixGet(MATRIX_MODE_MODELVIEW_PROJECTION), sizeof(DirectX::XMMATRIX));
d3d11->Unmap(c.m_projectionMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW_PROJECTION] = false;
}
@@ -78,17 +70,17 @@ void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelSh
if (c.matrixDirty[MATRIX_MODE_MODELVIEW_TEXTURE])
{
d3d11->Map(c.m_textureMatrix, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- std::memcpy(mapped.pData, this->MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
+ memcpy(mapped.pData, MatrixGet(MATRIX_MODE_MODELVIEW_TEXTURE), sizeof(DirectX::XMMATRIX));
d3d11->Unmap(c.m_textureMatrix, 0);
c.matrixDirty[MATRIX_MODE_MODELVIEW_TEXTURE] = false;
}
- this->UpdateFogState();
- this->UpdateViewportState();
- this->UpdateLightingState();
- this->UpdateTexGenState();
+ UpdateFogState();
+ UpdateViewportState();
+ UpdateLightingState();
+ UpdateTexGenState();
- d3d11->IASetPrimitiveTopology(m_Topologies[PrimitiveType]);
+ d3d11->IASetPrimitiveTopology(g_topologies[PrimitiveType]);
if (PrimitiveType == C4JRender::PRIMITIVE_TYPE_QUAD_LIST)
{
@@ -106,24 +98,23 @@ void Renderer::DrawVertexSetup(C4JRender::eVertexType vType, C4JRender::ePixelSh
return;
}
- d3d11->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0);
+ d3d11->IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0);
*indexed = false;
}
void Renderer::DrawVertices(C4JRender::ePrimitiveType PrimitiveType, int count, void *vertices, C4JRender::eVertexType vType,
C4JRender::ePixelShaderType psType)
{
- Renderer::Context &c = this->getContext();
+ PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertices", MP_RED2)
+ Renderer::Context &c = getContext();
ID3D11DeviceContext *d3d11 = c.m_pDeviceContext;
Renderer::CommandBuffer *commandBuffer = c.commandBuffer;
- if (commandBuffer != nullptr)
+ if (commandBuffer != NULL)
{
C4JRender::eVertexType effectiveVertexType = vType;
if (effectiveVertexType == C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1 && c.lightingEnabled)
- {
effectiveVertexType = C4JRender::VERTEX_TYPE_PF3_TF2_CB4_NB4_XW1_LIT;
- }
c.recordingPrimitiveType = PrimitiveType;
c.recordingVertexType = effectiveVertexType;
@@ -134,43 +125,37 @@ void Renderer::DrawVertices(C4JRender::ePrimitiveType PrimitiveType, int count,
int drawCount = count;
bool indexed = false;
- this->DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
+
+ PROFILER_SCOPE("Renderer::DrawVertices", "DrawVertexSetup", MP_RED2)
+ DrawVertexSetup(vType, psType, PrimitiveType, &drawCount, &indexed);
const UINT stride = vertexStrideTable[vType];
const UINT vertexBytes = stride * static_cast(count);
assert(vertexBytes <= Context::VERTEX_BUFFER_SIZE);
- if (c.dynamicVertexOffset + vertexBytes > Context::VERTEX_BUFFER_SIZE)
- {
- c.dynamicVertexOffset = 0;
- }
+ UINT vertexOffset = c.dynamicVertexOffset;
+ if (vertexOffset + vertexBytes > Context::VERTEX_BUFFER_SIZE)
+ vertexOffset = 0;
D3D11_MAPPED_SUBRESOURCE mapped = {};
- const D3D11_MAP mapType = c.dynamicVertexOffset == 0 ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE;
+ const D3D11_MAP mapType = vertexOffset == 0 ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE;
const HRESULT hr = d3d11->Map(c.dynamicVertexBuffer, 0, mapType, 0, &mapped);
- if (hr != 0)
- {
- std::printf("ERROR: 0x%x\n", static_cast(hr));
- }
+ if (FAILED(hr))
+ printf("ERROR: 0x%x\n", static_cast(hr));
- std::memcpy(static_cast(mapped.pData) + c.dynamicVertexOffset, vertices, vertexBytes);
+ memcpy(reinterpret_cast(mapped.pData) + vertexOffset, vertices, vertexBytes);
d3d11->Unmap(c.dynamicVertexBuffer, 0);
- this->StateUpdate();
+ StateUpdate();
ID3D11Buffer *dynamicBuffer = c.dynamicVertexBuffer;
- const UINT vertexOffset = c.dynamicVertexOffset;
d3d11->IASetVertexBuffers(0, 1, &dynamicBuffer, &stride, &vertexOffset);
if (indexed)
- {
d3d11->DrawIndexed(drawCount, 0, 0);
- }
else
- {
d3d11->Draw(count, 0);
- }
- c.dynamicVertexOffset += vertexBytes;
+ c.dynamicVertexOffset = vertexOffset + vertexBytes;
}
diff --git a/Windows_Libs/Dev/Render/libpng/png.c b/Windows_Libs/Dev/Render/libpng/png.c
index a0cad01..d429c52 100644
--- a/Windows_Libs/Dev/Render/libpng/png.c
+++ b/Windows_Libs/Dev/Render/libpng/png.c
@@ -1,9 +1,10 @@
+
/* png.c - location for general purpose libpng functions
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -13,34 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_55 Your_png_h_is_not_version_1_6_55;
-
-/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
- * corresponding macro definitions. This causes a compile time failure if
- * something is wrong but generates no code.
- *
- * (1) The first check is that the PNG_CHUNK(cHNK, index) 'index' values must
- * increment from 0 to the last value.
- */
-#define PNG_CHUNK(cHNK, index) != (index) || ((index)+1)
-
-#if 0 PNG_KNOWN_CHUNKS < 0
-# error PNG_KNOWN_CHUNKS chunk definitions are not in order
-#endif
-
-#undef PNG_CHUNK
-
-/* (2) The chunk name macros, png_cHNK, must all be valid and defined. Since
- * this is a preprocessor test undefined pp-tokens come out as zero and will
- * fail this test.
- */
-#define PNG_CHUNK(cHNK, index) !PNG_CHUNK_NAME_VALID(png_ ## cHNK) ||
-
-#if PNG_KNOWN_CHUNKS 0
-# error png_cHNK not defined for some known cHNK
-#endif
-
-#undef PNG_CHUNK
+typedef png_libpng_version_1_6_2 Your_png_h_is_not_version_1_6_2;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@@ -52,20 +26,15 @@ typedef png_libpng_version_1_6_55 Your_png_h_is_not_version_1_6_55;
void PNGAPI
png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
{
- unsigned int nb = (unsigned int)num_bytes;
-
png_debug(1, "in png_set_sig_bytes");
if (png_ptr == NULL)
return;
- if (num_bytes < 0)
- nb = 0;
-
- if (nb > 8)
+ if (num_bytes > 8)
png_error(png_ptr, "Too many bytes for PNG signature");
- png_ptr->sig_bytes = (png_byte)nb;
+ png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
}
/* Checks whether the supplied bytes match the PNG signature. We allow
@@ -77,48 +46,41 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
* PNG signature (this is the same behavior as strcmp, memcmp, etc).
*/
int PNGAPI
-png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
+png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
{
- static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
if (num_to_check > 8)
num_to_check = 8;
else if (num_to_check < 1)
- return -1;
+ return (-1);
if (start > 7)
- return -1;
+ return (-1);
if (start + num_to_check > 8)
num_to_check = 8 - start;
- return memcmp(&sig[start], &png_signature[start], num_to_check);
+ return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
}
-#endif /* READ */
+#endif /* PNG_READ_SUPPORTED */
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Function to allocate memory for zlib */
PNG_FUNCTION(voidpf /* PRIVATE */,
-png_zalloc,(voidpf png_ptr, uInt items, uInt size),
- PNG_ALLOCATED)
+png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
{
png_alloc_size_t num_bytes = size;
if (png_ptr == NULL)
return NULL;
- /* This check against overflow is vestigial, dating back from
- * the old times when png_zalloc used to be an exported function.
- * We're still keeping it here for now, as an extra-cautious
- * prevention against programming errors inside zlib, although it
- * should rather be a debug-time assertion instead.
- */
- if (size != 0 && items >= (~(png_alloc_size_t)0) / size)
+ if (items >= (~(png_alloc_size_t)0)/size)
{
- png_warning(png_voidcast(png_structrp, png_ptr),
- "Potential overflow in png_zalloc()");
+ png_warning (png_voidcast(png_structrp, png_ptr),
+ "Potential overflow in png_zalloc()");
return NULL;
}
@@ -139,7 +101,7 @@ png_zfree(voidpf png_ptr, voidpf ptr)
void /* PRIVATE */
png_reset_crc(png_structrp png_ptr)
{
- /* The cast is safe because the crc is a 32-bit value. */
+ /* The cast is safe because the crc is a 32 bit value. */
png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
}
@@ -149,11 +111,11 @@ png_reset_crc(png_structrp png_ptr)
* trouble of calculating it.
*/
void /* PRIVATE */
-png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
{
int need_crc = 1;
- if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
{
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
@@ -162,26 +124,24 @@ png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
else /* critical */
{
- if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
need_crc = 0;
}
/* 'uLong' is defined in zlib.h as unsigned long; this means that on some
- * systems it is a 64-bit value. crc32, however, returns 32 bits so the
+ * systems it is a 64 bit value. crc32, however, returns 32 bits so the
* following cast is safe. 'uInt' may be no more than 16 bits, so it is
* necessary to perform a loop here.
*/
- if (need_crc != 0 && length > 0)
+ if (need_crc && length > 0)
{
uLong crc = png_ptr->crc; /* Should never issue a warning */
do
{
uInt safe_length = (uInt)length;
-#ifndef __COVERITY__
if (safe_length == 0)
safe_length = (uInt)-1; /* evil, but safe */
-#endif
crc = crc32(crc, ptr, safe_length);
@@ -205,47 +165,52 @@ png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
int
png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
{
- /* Libpng versions 1.0.0 and later are binary compatible if the version
- * string matches through the second '.'; we must recompile any
- * applications that use any older library version.
- */
-
- if (user_png_ver != NULL)
+ if (user_png_ver)
{
- int i = -1;
- int found_dots = 0;
+ int i = 0;
do
{
- i++;
- if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
+ if (user_png_ver[i] != png_libpng_ver[i])
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- if (user_png_ver[i] == '.')
- found_dots++;
- } while (found_dots < 2 && user_png_ver[i] != 0 &&
- PNG_LIBPNG_VER_STRING[i] != 0);
+ } while (png_libpng_ver[i++]);
}
else
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
- if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
{
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first and third digits (note that when we reach version
+ * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]).
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && (user_png_ver[2] != png_libpng_ver[2] ||
+ user_png_ver[3] != png_libpng_ver[3])) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
#ifdef PNG_WARNINGS_SUPPORTED
- size_t pos = 0;
- char m[128];
+ size_t pos = 0;
+ char m[128];
- pos = png_safecat(m, (sizeof m), pos,
- "Application built with libpng-");
- pos = png_safecat(m, (sizeof m), pos, user_png_ver);
- pos = png_safecat(m, (sizeof m), pos, " but running with ");
- pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
- PNG_UNUSED(pos)
+ pos = png_safecat(m, (sizeof m), pos,
+ "Application built with libpng-");
+ pos = png_safecat(m, (sizeof m), pos, user_png_ver);
+ pos = png_safecat(m, (sizeof m), pos, " but running with ");
+ pos = png_safecat(m, (sizeof m), pos, png_libpng_ver);
- png_warning(png_ptr, m);
+ png_warning(png_ptr, m);
#endif
- return 0;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+
+ return 0;
+ }
}
/* Success return. */
@@ -258,8 +223,7 @@ png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
PNG_FUNCTION(png_structp /* PRIVATE */,
png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED)
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{
png_struct create_struct;
# ifdef PNG_SETJMP_SUPPORTED
@@ -272,23 +236,21 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
*/
memset(&create_struct, 0, (sizeof create_struct));
+ /* Added at libpng-1.2.6 */
# ifdef PNG_USER_LIMITS_SUPPORTED
create_struct.user_width_max = PNG_USER_WIDTH_MAX;
create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
# ifdef PNG_USER_CHUNK_CACHE_MAX
- create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+ /* Added at libpng-1.2.43 and 1.4.0 */
+ create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
# endif
-# if PNG_USER_CHUNK_MALLOC_MAX > 0 /* default to compile-time limit */
- create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
-
- /* No compile-time limit, so initialize to the system limit: */
-# elif defined PNG_MAX_MALLOC_64K /* legacy system limit */
- create_struct.user_chunk_malloc_max = 65536U;
-
-# else /* modern system limit SIZE_MAX (C99) */
- create_struct.user_chunk_malloc_max = PNG_SIZE_MAX;
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+ /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
+ * in png_struct regardless.
+ */
+ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
# endif
# endif
@@ -297,10 +259,6 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
*/
# ifdef PNG_USER_MEM_SUPPORTED
png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
-# else
- PNG_UNUSED(mem_ptr)
- PNG_UNUSED(malloc_fn)
- PNG_UNUSED(free_fn)
# endif
/* (*error_fn) can return control to the caller after the error_ptr is set,
@@ -312,9 +270,7 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
# ifdef PNG_SETJMP_SUPPORTED
if (!setjmp(create_jmp_buf))
-# endif
{
-# ifdef PNG_SETJMP_SUPPORTED
/* Temporarily fake out the longjmp information until we have
* successfully completed this function. This only works if we have
* setjmp() support compiled in, but it is safe - this stuff should
@@ -323,13 +279,15 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
create_struct.jmp_buf_ptr = &create_jmp_buf;
create_struct.jmp_buf_size = 0; /*stack allocation*/
create_struct.longjmp_fn = longjmp;
+# else
+ {
# endif
/* Call the general version checker (shared with read and write code):
*/
- if (png_user_version_check(&create_struct, user_png_ver) != 0)
+ if (png_user_version_check(&create_struct, user_png_ver))
{
png_structrp png_ptr = png_voidcast(png_structrp,
- png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+ png_malloc_warn(&create_struct, (sizeof *png_ptr)));
if (png_ptr != NULL)
{
@@ -341,10 +299,10 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
create_struct.zstream.opaque = png_ptr;
# ifdef PNG_SETJMP_SUPPORTED
- /* Eliminate the local error handling: */
- create_struct.jmp_buf_ptr = NULL;
- create_struct.jmp_buf_size = 0;
- create_struct.longjmp_fn = 0;
+ /* Eliminate the local error handling: */
+ create_struct.jmp_buf_ptr = NULL;
+ create_struct.jmp_buf_size = 0;
+ create_struct.longjmp_fn = 0;
# endif
*png_ptr = create_struct;
@@ -363,8 +321,7 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
/* Allocate the memory for an info_struct for the application. */
PNG_FUNCTION(png_infop,PNGAPI
-png_create_info_struct,(png_const_structrp png_ptr),
- PNG_ALLOCATED)
+png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
{
png_inforp info_ptr;
@@ -379,7 +336,7 @@ png_create_info_struct,(png_const_structrp png_ptr),
* has always been done in 'example.c'.
*/
info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
- (sizeof *info_ptr)));
+ (sizeof *info_ptr)));
if (info_ptr != NULL)
memset(info_ptr, 0, (sizeof *info_ptr));
@@ -434,8 +391,8 @@ png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
* those cases where it does anything other than a memset.
*/
PNG_FUNCTION(void,PNGAPI
-png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
- PNG_DEPRECATED)
+png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
+ PNG_DEPRECATED)
{
png_inforp info_ptr = *ptr_ptr;
@@ -450,9 +407,7 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
/* The following line is why this API should not be used: */
free(info_ptr);
info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
- (sizeof *info_ptr)));
- if (info_ptr == NULL)
- return;
+ (sizeof *info_ptr)));
*ptr_ptr = info_ptr;
}
@@ -460,9 +415,10 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
memset(info_ptr, 0, (sizeof *info_ptr));
}
+/* The following API is not called internally */
void PNGAPI
png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
- int freer, png_uint_32 mask)
+ int freer, png_uint_32 mask)
{
png_debug(1, "in png_data_freer");
@@ -481,7 +437,7 @@ png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
void PNGAPI
png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
- int num)
+ int num)
{
png_debug(1, "in png_free_data");
@@ -490,44 +446,42 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#ifdef PNG_TEXT_SUPPORTED
/* Free text item num or (if num == -1) all text items */
- if (info_ptr->text != NULL &&
- ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
{
if (num != -1)
{
- png_free(png_ptr, info_ptr->text[num].key);
- info_ptr->text[num].key = NULL;
+ if (info_ptr->text && info_ptr->text[num].key)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
}
else
{
int i;
-
for (i = 0; i < info_ptr->num_text; i++)
- png_free(png_ptr, info_ptr->text[i].key);
-
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
png_free(png_ptr, info_ptr->text);
info_ptr->text = NULL;
- info_ptr->num_text = 0;
- info_ptr->max_text = 0;
+ info_ptr->num_text=0;
}
}
#endif
#ifdef PNG_tRNS_SUPPORTED
/* Free any tRNS entry */
- if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
{
- info_ptr->valid &= ~PNG_INFO_tRNS;
png_free(png_ptr, info_ptr->trans_alpha);
info_ptr->trans_alpha = NULL;
- info_ptr->num_trans = 0;
+ info_ptr->valid &= ~PNG_INFO_tRNS;
}
#endif
#ifdef PNG_sCAL_SUPPORTED
/* Free any sCAL entry */
- if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->scal_s_width);
png_free(png_ptr, info_ptr->scal_s_height);
@@ -539,20 +493,20 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#ifdef PNG_pCAL_SUPPORTED
/* Free any pCAL entry */
- if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->pcal_purpose);
png_free(png_ptr, info_ptr->pcal_units);
info_ptr->pcal_purpose = NULL;
info_ptr->pcal_units = NULL;
-
if (info_ptr->pcal_params != NULL)
{
- int i;
-
+ unsigned int i;
for (i = 0; i < info_ptr->pcal_nparams; i++)
+ {
png_free(png_ptr, info_ptr->pcal_params[i]);
-
+ info_ptr->pcal_params[i] = NULL;
+ }
png_free(png_ptr, info_ptr->pcal_params);
info_ptr->pcal_params = NULL;
}
@@ -562,7 +516,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#ifdef PNG_iCCP_SUPPORTED
/* Free any profile entry */
- if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->iccp_name);
png_free(png_ptr, info_ptr->iccp_profile);
@@ -574,75 +528,68 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#ifdef PNG_sPLT_SUPPORTED
/* Free a given sPLT entry, or (if num == -1) all sPLT entries */
- if (info_ptr->splt_palettes != NULL &&
- ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
{
if (num != -1)
{
- png_free(png_ptr, info_ptr->splt_palettes[num].name);
- png_free(png_ptr, info_ptr->splt_palettes[num].entries);
- info_ptr->splt_palettes[num].name = NULL;
- info_ptr->splt_palettes[num].entries = NULL;
+ if (info_ptr->splt_palettes)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
}
else
{
- int i;
-
- for (i = 0; i < info_ptr->splt_palettes_num; i++)
+ if (info_ptr->splt_palettes_num)
{
- png_free(png_ptr, info_ptr->splt_palettes[i].name);
- png_free(png_ptr, info_ptr->splt_palettes[i].entries);
- }
+ int i;
+ for (i = 0; i < info_ptr->splt_palettes_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)i);
- png_free(png_ptr, info_ptr->splt_palettes);
- info_ptr->splt_palettes = NULL;
- info_ptr->splt_palettes_num = 0;
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ }
info_ptr->valid &= ~PNG_INFO_sPLT;
}
}
#endif
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
- if (info_ptr->unknown_chunks != NULL &&
- ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
{
if (num != -1)
{
- png_free(png_ptr, info_ptr->unknown_chunks[num].data);
- info_ptr->unknown_chunks[num].data = NULL;
+ if (info_ptr->unknown_chunks)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
}
else
{
int i;
- for (i = 0; i < info_ptr->unknown_chunks_num; i++)
- png_free(png_ptr, info_ptr->unknown_chunks[i].data);
+ if (info_ptr->unknown_chunks_num)
+ {
+ for (i = 0; i < info_ptr->unknown_chunks_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, (int)i);
- png_free(png_ptr, info_ptr->unknown_chunks);
- info_ptr->unknown_chunks = NULL;
- info_ptr->unknown_chunks_num = 0;
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
}
}
#endif
-#ifdef PNG_eXIf_SUPPORTED
- /* Free any eXIf entry */
- if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
- {
- if (info_ptr->exif)
- {
- png_free(png_ptr, info_ptr->exif);
- info_ptr->exif = NULL;
- }
- info_ptr->valid &= ~PNG_INFO_eXIf;
- }
-#endif
-
#ifdef PNG_hIST_SUPPORTED
/* Free any hIST entry */
- if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->hist);
info_ptr->hist = NULL;
@@ -651,7 +598,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#endif
/* Free any PLTE entry that was internally allocated */
- if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
{
png_free(png_ptr, info_ptr->palette);
info_ptr->palette = NULL;
@@ -661,14 +608,16 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* Free any image bits attached to the info structure */
- if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
+ if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
{
- if (info_ptr->row_pointers != NULL)
+ if (info_ptr->row_pointers)
{
png_uint_32 row;
for (row = 0; row < info_ptr->height; row++)
+ {
png_free(png_ptr, info_ptr->row_pointers[row]);
-
+ info_ptr->row_pointers[row] = NULL;
+ }
png_free(png_ptr, info_ptr->row_pointers);
info_ptr->row_pointers = NULL;
}
@@ -681,7 +630,7 @@ png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
info_ptr->free_me &= ~mask;
}
-#endif /* READ || WRITE */
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
/* This function returns a pointer to the io_ptr associated with the user
* functions. The application should free any memory associated with this
@@ -691,9 +640,9 @@ png_voidp PNGAPI
png_get_io_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return NULL;
+ return (NULL);
- return png_ptr->io_ptr;
+ return (png_ptr->io_ptr);
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
@@ -705,7 +654,7 @@ png_get_io_ptr(png_const_structrp png_ptr)
* function of your own because "FILE *" isn't necessarily available.
*/
void PNGAPI
-png_init_io(png_structrp png_ptr, FILE *fp)
+png_init_io(png_structrp png_ptr, png_FILE_p fp)
{
png_debug(1, "in png_init_io");
@@ -716,23 +665,22 @@ png_init_io(png_structrp png_ptr, FILE *fp)
}
# endif
-# ifdef PNG_SAVE_INT_32_SUPPORTED
-/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90
- * defines a cast of a signed integer to an unsigned integer either to preserve
- * the value, if it is positive, or to calculate:
- *
- * (UNSIGNED_MAX+1) + integer
- *
- * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
- * negative integral value is added the result will be an unsigned value
- * corresponding to the 2's complement representation.
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format. If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format. Note that,
+ * the following works correctly even if png_int_32 has more than 32 bits
+ * (compare the more complex code required on read for sign extension.)
*/
void PNGAPI
png_save_int_32(png_bytep buf, png_int_32 i)
{
- png_save_uint_32(buf, (png_uint_32)i);
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
}
-# endif
+#endif
# ifdef PNG_TIME_RFC1123_SUPPORTED
/* Convert the supplied time into an RFC 1123 string suitable for use in
@@ -741,7 +689,7 @@ png_save_int_32(png_bytep buf, png_int_32 i)
int PNGAPI
png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
{
- static const char short_months[12][4] =
+ static PNG_CONST char short_months[12][4] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
@@ -757,7 +705,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
{
size_t pos = 0;
- char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */
+ char number_buf[5]; /* enough for a four-digit year */
# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
# define APPEND_NUMBER(format, value)\
@@ -776,7 +724,6 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
APPEND(':');
APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
- PNG_UNUSED (pos)
# undef APPEND
# undef APPEND_NUMBER
@@ -786,7 +733,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
return 1;
}
-# if PNG_LIBPNG_VER < 10700
+# if PNG_LIBPNG_VER < 10700
/* To do: remove the following from libpng-1.7 */
/* Original API that uses a private buffer in png_struct.
* Deprecated because it causes png_struct to carry a spurious temporary
@@ -798,7 +745,7 @@ png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
if (png_ptr != NULL)
{
/* The only failure above if png_ptr != NULL is from an invalid ptime */
- if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
+ if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime))
png_warning(png_ptr, "Ignoring invalid time value");
else
@@ -807,10 +754,10 @@ png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
return NULL;
}
-# endif /* LIBPNG_VER < 10700 */
-# endif /* TIME_RFC1123 */
+# endif
+# endif /* PNG_TIME_RFC1123_SUPPORTED */
-#endif /* READ || WRITE */
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
png_const_charp PNGAPI
png_get_copyright(png_const_structrp png_ptr)
@@ -819,14 +766,19 @@ png_get_copyright(png_const_structrp png_ptr)
#ifdef PNG_STRING_COPYRIGHT
return PNG_STRING_COPYRIGHT
#else
+# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.55" PNG_STRING_NEWLINE \
- "Copyright (c) 2018-2026 Cosmin Truta" PNG_STRING_NEWLINE \
- "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
- PNG_STRING_NEWLINE \
- "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
- "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
- PNG_STRING_NEWLINE;
+ "libpng version 1.6.2 - April 25, 2013" PNG_STRING_NEWLINE \
+ "Copyright (c) 1998-2013 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+ PNG_STRING_NEWLINE;
+# else
+ return "libpng version 1.6.2 - April 25, 2013\
+ Copyright (c) 1998-2013 Glenn Randers-Pehrson\
+ Copyright (c) 1996-1997 Andreas Dilger\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
+# endif
#endif
}
@@ -861,71 +813,14 @@ png_get_header_version(png_const_structrp png_ptr)
#ifdef __STDC__
return PNG_HEADER_VERSION_STRING
# ifndef PNG_READ_SUPPORTED
- " (NO READ SUPPORT)"
+ " (NO READ SUPPORT)"
# endif
- PNG_STRING_NEWLINE;
+ PNG_STRING_NEWLINE;
#else
return PNG_HEADER_VERSION_STRING;
#endif
}
-#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-/* NOTE: this routine is not used internally! */
-/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
- * large of png_color. This lets grayscale images be treated as
- * paletted. Most useful for gamma correction and simplification
- * of code. This API is not used internally.
- */
-void PNGAPI
-png_build_grayscale_palette(int bit_depth, png_colorp palette)
-{
- int num_palette;
- int color_inc;
- int i;
- int v;
-
- png_debug(1, "in png_do_build_grayscale_palette");
-
- if (palette == NULL)
- return;
-
- switch (bit_depth)
- {
- case 1:
- num_palette = 2;
- color_inc = 0xff;
- break;
-
- case 2:
- num_palette = 4;
- color_inc = 0x55;
- break;
-
- case 4:
- num_palette = 16;
- color_inc = 0x11;
- break;
-
- case 8:
- num_palette = 256;
- color_inc = 1;
- break;
-
- default:
- num_palette = 0;
- color_inc = 0;
- break;
- }
-
- for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
- {
- palette[i].red = (png_byte)(v & 0xff);
- palette[i].green = (png_byte)(v & 0xff);
- palette[i].blue = (png_byte)(v & 0xff);
- }
-}
-#endif
-
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
int PNGAPI
png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
@@ -941,13 +836,13 @@ png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
/* The code is the fifth byte after each four byte string. Historically this
* code was always searched from the end of the list, this is no longer
- * necessary because the 'set' routine handles duplicate entries correctly.
+ * necessary because the 'set' routine handles duplicate entries correcty.
*/
do /* num_chunk_list > 0, so at least one */
{
p -= 5;
- if (memcmp(chunk_name, p, 4) == 0)
+ if (!memcmp(chunk_name, p, 4))
return p[4];
}
while (p > p_end);
@@ -960,8 +855,7 @@ png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
return PNG_HANDLE_CHUNK_AS_DEFAULT;
}
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
int /* PRIVATE */
png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
{
@@ -970,7 +864,7 @@ png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
return png_handle_as_unknown(png_ptr, chunk_string);
}
-#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+#endif /* READ_UNKNOWN_CHUNKS */
#endif /* SET_UNKNOWN_CHUNKS */
#ifdef PNG_READ_SUPPORTED
@@ -982,18 +876,20 @@ png_reset_zstream(png_structrp png_ptr)
return Z_STREAM_ERROR;
/* WARNING: this resets the window bits to the maximum! */
- return inflateReset(&png_ptr->zstream);
+ return (inflateReset(&png_ptr->zstream));
}
-#endif /* READ */
+#endif /* PNG_READ_SUPPORTED */
/* This function was added to libpng-1.0.7 */
png_uint_32 PNGAPI
png_access_version_number(void)
{
/* Version of *.c files used when building libpng */
- return (png_uint_32)PNG_LIBPNG_VER;
+ return((png_uint_32)PNG_LIBPNG_VER);
}
+
+
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
* If it doesn't 'ret' is used to set it to something appropriate, even in cases
@@ -1065,169 +961,227 @@ png_zstream_error(png_structrp png_ptr, int ret)
}
}
-#ifdef PNG_COLORSPACE_SUPPORTED
-static png_int_32
-png_fp_add(png_int_32 addend0, png_int_32 addend1, int *error)
-{
- /* Safely add two fixed point values setting an error flag and returning 0.5
- * on overflow.
- * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
- * relying on addition of two positive values producing a negative one is not
- * safe.
- */
- if (addend0 > 0)
- {
- if (0x7fffffff - addend0 >= addend1)
- return addend0+addend1;
- }
- else if (addend0 < 0)
- {
- if (-0x7fffffff - addend0 <= addend1)
- return addend0+addend1;
- }
- else
- return addend1;
-
- *error = 1;
- return PNG_FP_1/2;
-}
-
-static png_int_32
-png_fp_sub(png_int_32 addend0, png_int_32 addend1, int *error)
-{
- /* As above but calculate addend0-addend1. */
- if (addend1 > 0)
- {
- if (-0x7fffffff + addend1 <= addend0)
- return addend0-addend1;
- }
- else if (addend1 < 0)
- {
- if (0x7fffffff + addend1 >= addend0)
- return addend0-addend1;
- }
- else
- return addend0;
-
- *error = 1;
- return PNG_FP_1/2;
-}
+/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
+ * at libpng 1.5.5!
+ */
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
static int
-png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1,
- png_int_32 addend2)
-{
- /* Safely add three integers. Returns 0 on success, 1 on overflow. Does not
- * set the result on overflow.
+png_colorspace_check_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+ /* This is called to check a new gamma value against an existing one. The
+ * routine returns false if the new gamma value should not be written.
+ *
+ * 'from' says where the new gamma value comes from:
+ *
+ * 0: the new gamma value is the libpng estimate for an ICC profile
+ * 1: the new gamma value comes from a gAMA chunk
+ * 2: the new gamma value comes from an sRGB chunk
*/
- int error = 0;
- int result = png_fp_add(*addend0_and_result,
- png_fp_add(addend1, addend2, &error),
- &error);
- if (!error) *addend0_and_result = result;
- return error;
+{
+ png_fixed_point gtest;
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ (!png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) ||
+ png_gamma_significant(gtest)))
+ {
+ /* Either this is an sRGB image, in which case the calculated gamma
+ * approximation should match, or this is an image with a profile and the
+ * value libpng calculates for the gamma of the profile does not match the
+ * value recorded in the file. The former, sRGB, case is an error, the
+ * latter is just a warning.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
+ {
+ png_chunk_report(png_ptr, "gamma value does not match sRGB",
+ PNG_CHUNK_ERROR);
+ /* Do not overwrite an sRGB value */
+ return from == 2;
+ }
+
+ else /* sRGB tag not involved */
+ {
+ png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
+ PNG_CHUNK_WARNING);
+ return from == 1;
+ }
+ }
+
+ return 1;
}
+void /* PRIVATE */
+png_colorspace_set_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA)
+{
+ /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
+ * occur. Since the fixed point representation is assymetrical it is
+ * possible for 1/gamma to overflow the limit of 21474 and this means the
+ * gamma value must be at least 5/100000 and hence at most 20000.0. For
+ * safety the limits here are a little narrower. The values are 0.00016 to
+ * 6250.0, which are truly ridiculous gamma values (and will produce
+ * displays that are all black or all white.)
+ *
+ * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
+ * handling code, which only required the value to be >0.
+ */
+ png_const_charp errmsg;
+
+ if (gAMA < 16 || gAMA > 625000000)
+ errmsg = "gamma value out of range";
+
+# ifdef PNG_READ_gAMA_SUPPORTED
+ /* Allow the application to set the gamma value more than once */
+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
+ errmsg = "duplicate";
+# endif
+
+ /* Do nothing if the colorspace is already invalid */
+ else if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ else
+ {
+ if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/))
+ {
+ /* Store this gamma value. */
+ colorspace->gamma = gAMA;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
+ }
+
+ /* At present if the check_gamma test fails the gamma of the colorspace is
+ * not updated however the colorspace is not invalidated. This
+ * corresponds to the case where the existing gamma comes from an sRGB
+ * chunk or profile. An error message has already been output.
+ */
+ return;
+ }
+
+ /* Error exit - errmsg has been set. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
+}
+
+void /* PRIVATE */
+png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ {
+ /* Everything is invalid */
+ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
+ PNG_INFO_iCCP);
+
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Clean up the iCCP profile now if it won't be used. */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ }
+
+ else
+ {
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Leave the INFO_iCCP flag set if the pngset.c code has already set
+ * it; this allows a PNG to contain a profile which matches sRGB and
+ * yet still have that profile retrievable by the application.
+ */
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB)
+ info_ptr->valid |= PNG_INFO_sRGB;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_sRGB;
+
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)
+ info_ptr->valid |= PNG_INFO_cHRM;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_cHRM;
+# endif
+
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA)
+ info_ptr->valid |= PNG_INFO_gAMA;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_gAMA;
+ }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void /* PRIVATE */
+png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if (info_ptr == NULL) /* reduce code size; check here not in the caller */
+ return;
+
+ info_ptr->colorspace = png_ptr->colorspace;
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
* cHRM, as opposed to using chromaticities. These internal APIs return
* non-zero on a parameter error. The X, Y and Z values are required to be
* positive and less than 1.0.
*/
-int /* PRIVATE */
+static int
png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
{
- /* NOTE: returns 0 on success, 1 means error. */
- png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY;
+ png_int_32 d, dwhite, whiteX, whiteY;
- /* 'd' in each of the blocks below is just X+Y+Z for each component,
- * x, y and z are X,Y,Z/(X+Y+Z).
- */
- d = XYZ->red_X;
- if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z))
- return 1;
- dred = d;
- if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, dred) == 0)
- return 1;
- if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, dred) == 0)
- return 1;
-
- d = XYZ->green_X;
- if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z))
- return 1;
- dgreen = d;
- if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, dgreen) == 0)
- return 1;
- if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, dgreen) == 0)
- return 1;
-
- d = XYZ->blue_X;
- if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z))
- return 1;
- dblue = d;
- if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, dblue) == 0)
- return 1;
- if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, dblue) == 0)
- return 1;
-
- /* The reference white is simply the sum of the end-point (X,Y,Z) vectors so
- * the fillowing calculates (X+Y+Z) of the reference white (media white,
- * encoding white) itself:
- */
- d = dblue;
- if (png_safe_add(&d, dred, dgreen))
- return 1;
+ d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
+ if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1;
dwhite = d;
+ whiteX = XYZ->red_X;
+ whiteY = XYZ->red_Y;
- /* Find the white X,Y values from the sum of the red, green and blue X,Y
- * values.
+ d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
+ if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1;
+ dwhite += d;
+ whiteX += XYZ->green_X;
+ whiteY += XYZ->green_Y;
+
+ d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
+ if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1;
+ dwhite += d;
+ whiteX += XYZ->blue_X;
+ whiteY += XYZ->blue_Y;
+
+ /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
+ * thus:
*/
- d = XYZ->red_X;
- if (png_safe_add(&d, XYZ->green_X, XYZ->blue_X))
- return 1;
- whiteX = d;
-
- d = XYZ->red_Y;
- if (png_safe_add(&d, XYZ->green_Y, XYZ->blue_Y))
- return 1;
- whiteY = d;
-
- if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
- return 1;
- if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
- return 1;
+ if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
+ if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
return 0;
}
-int /* PRIVATE */
+static int
png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
{
- /* NOTE: returns 0 on success, 1 means error. */
png_fixed_point red_inverse, green_inverse, blue_scale;
png_fixed_point left, right, denominator;
/* Check xy and, implicitly, z. Note that wide gamut color spaces typically
* have end points with 0 tristimulus values (these are impossible end
- * points, but they are used to cover the possible colors). We check
- * xy->whitey against 5, not 0, to avoid a possible integer overflow.
- *
- * The limits here will *not* accept ACES AP0, where bluey is -7700
- * (-0.0770) because the PNG spec itself requires the xy values to be
- * unsigned. whitey is also required to be 5 or more to avoid overflow.
- *
- * Instead the upper limits have been relaxed to accomodate ACES AP1 where
- * redz ends up as -600 (-0.006). ProPhotoRGB was already "in range."
- * The new limit accomodates the AP0 and AP1 ranges for z but not AP0 redy.
+ * points, but they are used to cover the possible colors.)
*/
- const png_fixed_point fpLimit = PNG_FP_1+(PNG_FP_1/10);
- if (xy->redx < 0 || xy->redx > fpLimit) return 1;
- if (xy->redy < 0 || xy->redy > fpLimit-xy->redx) return 1;
- if (xy->greenx < 0 || xy->greenx > fpLimit) return 1;
- if (xy->greeny < 0 || xy->greeny > fpLimit-xy->greenx) return 1;
- if (xy->bluex < 0 || xy->bluex > fpLimit) return 1;
- if (xy->bluey < 0 || xy->bluey > fpLimit-xy->bluex) return 1;
- if (xy->whitex < 0 || xy->whitex > fpLimit) return 1;
- if (xy->whitey < 5 || xy->whitey > fpLimit-xy->whitex) return 1;
+ if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
+ if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
+ if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
+ if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
+ if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
+ if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
+ if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
+ if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
/* The reverse calculation is more difficult because the original tristimulus
* value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
@@ -1302,7 +1256,7 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
* (1/white-y), so we can immediately see that as white-y approaches 0 the
* accuracy inherent in the cHRM chunk drops off substantially.
*
- * libpng arithmetic: a simple inversion of the above equations
+ * libpng arithmetic: a simple invertion of the above equations
* ------------------------------------------------------------
*
* white_scale = 1/white-y
@@ -1372,23 +1326,18 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
* (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
*
* Accuracy:
- * The input values have 5 decimal digits of accuracy.
- *
- * In the previous implementation the values were all in the range 0 < value
- * < 1, so simple products are in the same range but may need up to 10
- * decimal digits to preserve the original precision and avoid underflow.
- * Because we are using a 32-bit signed representation we cannot match this;
- * the best is a little over 9 decimal digits, less than 10.
- *
- * This range has now been extended to allow values up to 1.1, or 110,000 in
- * fixed point.
+ * The input values have 5 decimal digits of accuracy. The values are all in
+ * the range 0 < value < 1, so simple products are in the same range but may
+ * need up to 10 decimal digits to preserve the original precision and avoid
+ * underflow. Because we are using a 32-bit signed representation we cannot
+ * match this; the best is a little over 9 decimal digits, less than 10.
*
* The approach used here is to preserve the maximum precision within the
* signed representation. Because the red-scale calculation above uses the
- * difference between two products of values that must be in the range
- * -1.1..+1.1 it is sufficient to divide the product by 8;
- * ceil(121,000/32767*2). The factor is irrelevant in the calculation
- * because it is applied to both numerator and denominator.
+ * difference between two products of values that must be in the range -1..+1
+ * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
+ * factor is irrelevant in the calculation because it is applied to both
+ * numerator and denominator.
*
* Note that the values of the differences of the products of the
* chromaticities in the above equations tend to be small, for example for
@@ -1410,93 +1359,297 @@ png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
* Adobe Wide Gamut RGB
* 0.258728243040113 0.724682314948566 0.016589442011321
*/
- {
- int error = 0;
-
- /* By the argument above overflow should be impossible here, however the
- * code now simply returns a failure code. The xy subtracts in the
- * arguments to png_muldiv are *not* checked for overflow because the
- * checks at the start guarantee they are in the range 0..110000 and
- * png_fixed_point is a 32-bit signed number.
- */
- if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0)
- return 1;
- if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) ==
- 0)
- return 1;
- denominator = png_fp_sub(left, right, &error);
- if (error) return 1;
-
- /* Now find the red numerator. */
- if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
- return 1;
- if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) ==
- 0)
- return 1;
-
- /* Overflow is possible here and it indicates an extreme set of PNG cHRM
- * chunk values. This calculation actually returns the reciprocal of the
- * scale value because this allows us to delay the multiplication of
- * white-y into the denominator, which tends to produce a small number.
- */
- if (png_muldiv(&red_inverse, xy->whitey, denominator,
- png_fp_sub(left, right, &error)) == 0 || error ||
- red_inverse <= xy->whitey /* r+g+b scales = white scale */)
- return 1;
-
- /* Similarly for green_inverse: */
- if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0)
- return 1;
- if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
- return 1;
- if (png_muldiv(&green_inverse, xy->whitey, denominator,
- png_fp_sub(left, right, &error)) == 0 || error ||
- green_inverse <= xy->whitey)
- return 1;
-
- /* And the blue scale, the checks above guarantee this can't overflow but
- * it can still produce 0 for extreme cHRM values.
- */
- blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey),
- png_reciprocal(red_inverse), &error),
- png_reciprocal(green_inverse), &error);
- if (error || blue_scale <= 0)
- return 1;
- }
-
- /* And fill in the png_XYZ. Again the subtracts are safe because of the
- * checks on the xy values at the start (the subtracts just calculate the
- * corresponding z values.)
+ /* By the argument, above overflow should be impossible here. The return
+ * value of 2 indicates an internal error to the caller.
*/
- if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
- return 1;
- if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
- return 1;
- if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
- red_inverse) == 0)
+ if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7))
+ return 2;
+ denominator = left - right;
+
+ /* Now find the red numerator. */
+ if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7))
+ return 2;
+
+ /* Overflow is possible here and it indicates an extreme set of PNG cHRM
+ * chunk values. This calculation actually returns the reciprocal of the
+ * scale value because this allows us to delay the multiplication of white-y
+ * into the denominator, which tends to produce a small number.
+ */
+ if (!png_muldiv(&red_inverse, xy->whitey, denominator, left-right) ||
+ red_inverse <= xy->whitey /* r+g+b scales = white scale */)
return 1;
- if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
- return 1;
- if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
- return 1;
- if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
- green_inverse) == 0)
+ /* Similarly for green_inverse: */
+ if (!png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&green_inverse, xy->whitey, denominator, left-right) ||
+ green_inverse <= xy->whitey)
return 1;
- if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
+ /* And the blue scale, the checks above guarantee this can't overflow but it
+ * can still produce 0 for extreme cHRM values.
+ */
+ blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
+ png_reciprocal(green_inverse);
+ if (blue_scale <= 0) return 1;
+
+
+ /* And fill in the png_XYZ: */
+ if (!png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1;
+ if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1;
+ if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
+ red_inverse))
return 1;
- if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
+
+ if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse))
return 1;
- if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
- PNG_FP_1) == 0)
+ if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse))
+ return 1;
+ if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
+ green_inverse))
+ return 1;
+
+ if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1;
+ if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1;
+ if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
+ PNG_FP_1))
return 1;
return 0; /*success*/
}
-#endif /* COLORSPACE */
-#ifdef PNG_READ_iCCP_SUPPORTED
+static int
+png_XYZ_normalize(png_XYZ *XYZ)
+{
+ png_int_32 Y;
+
+ if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
+ XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
+ XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
+ return 1;
+
+ /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
+ * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
+ * relying on addition of two positive values producing a negative one is not
+ * safe.
+ */
+ Y = XYZ->red_Y;
+ if (0x7fffffff - Y < XYZ->green_X) return 1;
+ Y += XYZ->green_Y;
+ if (0x7fffffff - Y < XYZ->blue_X) return 1;
+ Y += XYZ->blue_Y;
+
+ if (Y != PNG_FP_1)
+ {
+ if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1;
+
+ if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1;
+
+ if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1;
+ }
+
+ return 0;
+}
+
+static int
+png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
+{
+ /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
+ return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
+ PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
+ PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
+ PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
+ PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
+ PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta));
+}
+
+/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
+ * chunk chromaticities. Earlier checks used to simply look for the overflow
+ * condition (where the determinant of the matrix to solve for XYZ ends up zero
+ * because the chromaticity values are not all distinct.) Despite this it is
+ * theoretically possible to produce chromaticities that are apparently valid
+ * but that rapidly degrade to invalid, potentially crashing, sets because of
+ * arithmetic inaccuracies when calculations are performed on them. The new
+ * check is to round-trip xy -> XYZ -> xy and then check that the result is
+ * within a small percentage of the original.
+ */
+static int
+png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+ int result;
+ png_xy xy_test;
+
+ /* As a side-effect this routine also returns the XYZ endpoints. */
+ result = png_XYZ_from_xy(XYZ, xy);
+ if (result) return result;
+
+ result = png_xy_from_XYZ(&xy_test, XYZ);
+ if (result) return result;
+
+ if (png_colorspace_endpoints_match(xy, &xy_test,
+ 5/*actually, the math is pretty accurate*/))
+ return 0;
+
+ /* Too much slip */
+ return 1;
+}
+
+/* This is the check going the other way. The XYZ is modified to normalize it
+ * (another side-effect) and the xy chromaticities are returned.
+ */
+static int
+png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
+{
+ int result;
+ png_XYZ XYZtemp;
+
+ result = png_XYZ_normalize(XYZ);
+ if (result) return result;
+
+ result = png_xy_from_XYZ(xy, XYZ);
+ if (result) return result;
+
+ XYZtemp = *XYZ;
+ return png_colorspace_check_xy(&XYZtemp, xy);
+}
+
+/* Used to check for an endpoint match against sRGB */
+static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
+{
+ /* color x y */
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000,
+ /* white */ 31270, 32900
+};
+
+static int
+png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+ int preferred)
+{
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ /* The consistency check is performed on the chromaticities; this factors out
+ * variations because of the normalization (or not) of the end point Y
+ * values.
+ */
+ if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ /* The end points must be reasonably close to any we already have. The
+ * following allows an error of up to +/-.001
+ */
+ if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100))
+ {
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "inconsistent chromaticities");
+ return 0; /* failed */
+ }
+
+ /* Only overwrite with preferred values */
+ if (!preferred)
+ return 1; /* ok, but no change */
+ }
+
+ colorspace->end_points_xy = *xy;
+ colorspace->end_points_XYZ = *XYZ;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
+
+ /* The end points are normally quoted to two decimal digits, so allow +/-0.01
+ * on this test.
+ */
+ if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000))
+ colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
+
+ else
+ colorspace->flags &= PNG_COLORSPACE_CANCEL(
+ PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ return 2; /* ok and changed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_chromaticities(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, int preferred)
+{
+ /* We must check the end points to ensure they are reasonable - in the past
+ * color management systems have crashed as a result of getting bogus
+ * colorant values, while this isn't the fault of libpng it is the
+ * responsibility of libpng because PNG carries the bomb and libpng is in a
+ * position to protect against it.
+ */
+ png_XYZ XYZ;
+
+ switch (png_colorspace_check_xy(&XYZ, xy))
+ {
+ case 0: /* success */
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* We can't invert the chromaticities so we can't produce value XYZ
+ * values. Likely as not a color management system will fail too.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid chromaticities");
+ break;
+
+ default:
+ /* libpng is broken; this should be a warning but if it happens we
+ * want error reports so for the moment it is an error.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ break;
+ }
+
+ return 0; /* failed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_endpoints(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+{
+ png_XYZ XYZ = *XYZ_in;
+ png_xy xy;
+
+ switch (png_colorspace_check_XYZ(&xy, &XYZ))
+ {
+ case 0:
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* End points are invalid. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid end points");
+ break;
+
+ default:
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ break;
+ }
+
+ return 0; /* failed */
+}
+
+#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
/* Error message generation */
static char
png_icc_tag_char(png_uint_32 byte)
@@ -1526,8 +1679,7 @@ is_ICC_signature_char(png_alloc_size_t it)
(it >= 97 && it <= 122);
}
-static int
-is_ICC_signature(png_alloc_size_t it)
+static int is_ICC_signature(png_alloc_size_t it)
{
return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
is_ICC_signature_char((it >> 16) & 0xff) &&
@@ -1536,16 +1688,19 @@ is_ICC_signature(png_alloc_size_t it)
}
static int
-png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name,
- png_alloc_size_t value, png_const_charp reason)
+png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_alloc_size_t value, png_const_charp reason)
{
size_t pos;
char message[196]; /* see below for calculation */
+ if (colorspace != NULL)
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+
pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
- if (is_ICC_signature(value) != 0)
+ if (is_ICC_signature(value))
{
/* So 'value' is at most 4 bytes and the following cast is safe */
png_icc_tag_name(message+pos, (png_uint_32)value);
@@ -1555,24 +1710,121 @@ png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name,
}
# ifdef PNG_WARNINGS_SUPPORTED
else
- {
- char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
+ {
+ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
- pos = png_safecat(message, (sizeof message), pos,
- png_format_number(number, number+(sizeof number),
- PNG_NUMBER_FORMAT_x, value));
- pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
- }
+ pos = png_safecat(message, (sizeof message), pos,
+ png_format_number(number, number+(sizeof number),
+ PNG_NUMBER_FORMAT_x, value));
+ pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
+ }
# endif
/* The 'reason' is an arbitrary message, allow +79 maximum 195 */
pos = png_safecat(message, (sizeof message), pos, reason);
- PNG_UNUSED(pos)
- png_chunk_benign_error(png_ptr, message);
+ /* This is recoverable, but make it unconditionally an app_error on write to
+ * avoid writing invalid ICC profiles into PNG files. (I.e. we handle them
+ * on read, with a warning, but on write unless the app turns off
+ * application errors the PNG won't be written.)
+ */
+ png_chunk_report(png_ptr, message,
+ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
return 0;
}
+#endif /* sRGB || iCCP */
+#ifdef PNG_sRGB_SUPPORTED
+int /* PRIVATE */
+png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ int intent)
+{
+ /* sRGB sets known gamma, end points and (from the chunk) intent. */
+ /* IMPORTANT: these are not necessarily the values found in an ICC profile
+ * because ICC profiles store values adapted to a D50 environment; it is
+ * expected that the ICC profile mediaWhitePointTag will be D50, see the
+ * checks and code elsewhere to understand this better.
+ *
+ * These XYZ values, which are accurate to 5dp, produce rgb to gray
+ * coefficients of (6968,23435,2366), which are reduced (because they add up
+ * to 32769 not 32768) to (6968,23434,2366). These are the values that
+ * libpng has traditionally used (and are the best values given the 15bit
+ * algorithm used by the rgb to gray code.)
+ */
+ static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
+ {
+ /* color X Y Z */
+ /* red */ 41239, 21264, 1933,
+ /* green */ 35758, 71517, 11919,
+ /* blue */ 18048, 7219, 95053
+ };
+
+ /* Do nothing if the colorspace is already invalidated. */
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ /* Check the intent, then check for existing settings. It is valid for the
+ * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
+ * be consistent with the correct values. If, however, this function is
+ * called below because an iCCP chunk matches sRGB then it is quite
+ * conceivable that an older app recorded incorrect gAMA and cHRM because of
+ * an incorrect calculation based on the values in the profile - this does
+ * *not* invalidate the profile (though it still produces an error, which can
+ * be ignored.)
+ */
+ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (unsigned)intent, "invalid sRGB rendering intent");
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
+ colorspace->rendering_intent != intent)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (unsigned)intent, "inconsistent rendering intents");
+
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
+ {
+ png_benign_error(png_ptr, "duplicate sRGB information ignored");
+ return 0;
+ }
+
+ /* If the standard sRGB cHRM chunk does not match the one from the PNG file
+ * warn but overwrite the value with the correct one.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
+ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+ 100))
+ png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
+ PNG_CHUNK_ERROR);
+
+ /* This check is just done for the error reporting - the routine always
+ * returns true when the 'from' argument corresponds to sRGB (2).
+ */
+ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
+ 2/*from sRGB*/);
+
+ /* intent: bugs in GCC force 'int' to be used as the parameter type. */
+ colorspace->rendering_intent = (png_uint_16)intent;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
+
+ /* endpoints */
+ colorspace->end_points_xy = sRGB_xy;
+ colorspace->end_points_XYZ = sRGB_XYZ;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ /* gamma */
+ colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Finally record that we have an sRGB profile */
+ colorspace->flags |=
+ (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
+
+ return 1; /* set */
+}
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
* is XYZ(0.9642,1.0,0.8249), which scales to:
*
@@ -1581,38 +1833,24 @@ png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name,
static const png_byte D50_nCIEXYZ[12] =
{ 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
-static int /* bool */
-icc_check_length(png_const_structrp png_ptr, png_const_charp name,
- png_uint_32 profile_length)
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length)
{
if (profile_length < 132)
- return png_icc_profile_error(png_ptr, name, profile_length, "too short");
- return 1;
-}
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "too short");
-int /* PRIVATE */
-png_icc_check_length(png_const_structrp png_ptr, png_const_charp name,
- png_uint_32 profile_length)
-{
- if (!icc_check_length(png_ptr, name, profile_length))
- return 0;
-
- /* This needs to be here because the 'normal' check is in
- * png_decompress_chunk, yet this happens after the attempt to
- * png_malloc_base the required data. We only need this on read; on write
- * the caller supplies the profile buffer so libpng doesn't allocate it. See
- * the call to icc_check_length below (the write case).
- */
- if (profile_length > png_chunk_max(png_ptr))
- return png_icc_profile_error(png_ptr, name, profile_length,
- "profile too long");
+ if (profile_length & 3)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "invalid length");
return 1;
}
int /* PRIVATE */
-png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
- png_uint_32 profile_length,
+png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
png_const_bytep profile/* first 132 bytes only */, int color_type)
{
png_uint_32 temp;
@@ -1624,34 +1862,29 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
*/
temp = png_get_uint_32(profile);
if (temp != profile_length)
- return png_icc_profile_error(png_ptr, name, temp,
- "length does not match profile");
-
- temp = (png_uint_32) (*(profile+8));
- if (temp > 3 && (profile_length & 3))
- return png_icc_profile_error(png_ptr, name, profile_length,
- "invalid length");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "length does not match profile");
temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
profile_length < 132+12*temp) /* truncated tag table */
- return png_icc_profile_error(png_ptr, name, temp,
- "tag count too large");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "tag count too large");
/* The 'intent' must be valid or we can't store it, ICC limits the intent to
* 16 bits.
*/
temp = png_get_uint_32(profile+64);
if (temp >= 0xffff) /* The ICC limit */
- return png_icc_profile_error(png_ptr, name, temp,
- "invalid rendering intent");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid rendering intent");
/* This is just a warning because the profile may be valid in future
* versions.
*/
if (temp >= PNG_sRGB_INTENT_LAST)
- (void)png_icc_profile_error(png_ptr, name, temp,
- "intent outside defined range");
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "intent outside defined range");
/* At this point the tag table can't be checked because it hasn't necessarily
* been loaded; however, various header fields can be checked. These checks
@@ -1661,14 +1894,14 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
*/
/* Data checks (could be skipped). These checks must be independent of the
- * version number; however, the version number doesn't accommodate changes in
+ * version number; however, the version number doesn't accomodate changes in
* the header fields (just the known tags and the interpretation of the
* data.)
*/
temp = png_get_uint_32(profile+36); /* signature 'ascp' */
if (temp != 0x61637370)
- return png_icc_profile_error(png_ptr, name, temp,
- "invalid signature");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid signature");
/* Currently the PCS illuminant/adopted white point (the computational
* white point) are required to be D50,
@@ -1678,8 +1911,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
* following is just a warning.
*/
if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
- (void)png_icc_profile_error(png_ptr, name, 0/*no tag value*/,
- "PCS illuminant is not D50");
+ (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
+ "PCS illuminant is not D50");
/* The PNG spec requires this:
* "If the iCCP chunk is present, the image samples conform to the colour
@@ -1705,20 +1938,20 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
switch (temp)
{
case 0x52474220: /* 'RGB ' */
- if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
- return png_icc_profile_error(png_ptr, name, temp,
- "RGB color space not permitted on grayscale PNG");
+ if (!(color_type & PNG_COLOR_MASK_COLOR))
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "RGB color space not permitted on grayscale PNG");
break;
case 0x47524159: /* 'GRAY' */
- if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
- return png_icc_profile_error(png_ptr, name, temp,
- "Gray color space not permitted on RGB PNG");
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "Gray color space not permitted on RGB PNG");
break;
default:
- return png_icc_profile_error(png_ptr, name, temp,
- "invalid ICC profile color space");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid ICC profile color space");
}
/* It is up to the application to check that the profile class matches the
@@ -1733,8 +1966,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
temp = png_get_uint_32(profile+12); /* profile/device class */
switch (temp)
{
- case 0x73636e72: /* 'scnr' */
- case 0x6d6e7472: /* 'mntr' */
+ case 0x73636E72: /* 'scnr' */
+ case 0x6D6E7472: /* 'mntr' */
case 0x70727472: /* 'prtr' */
case 0x73706163: /* 'spac' */
/* All supported */
@@ -1742,26 +1975,26 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
case 0x61627374: /* 'abst' */
/* May not be embedded in an image */
- return png_icc_profile_error(png_ptr, name, temp,
- "invalid embedded Abstract ICC profile");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid embedded Abstract ICC profile");
- case 0x6c696e6b: /* 'link' */
- /* DeviceLink profiles cannot be interpreted in a non-device specific
+ case 0x6C696E6B: /* 'link' */
+ /* DeviceLink profiles cannnot be interpreted in a non-device specific
* fashion, if an app uses the AToB0Tag in the profile the results are
* undefined unless the result is sent to the intended device,
* therefore a DeviceLink profile should not be found embedded in a
* PNG.
*/
- return png_icc_profile_error(png_ptr, name, temp,
- "unexpected DeviceLink ICC profile class");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected DeviceLink ICC profile class");
- case 0x6e6d636c: /* 'nmcl' */
+ case 0x6E6D636C: /* 'nmcl' */
/* A NamedColor profile is also device specific, however it doesn't
- * contain an AToB0 tag that is open to misinterpretation. Almost
+ * contain an AToB0 tag that is open to misintrepretation. Almost
* certainly it will fail the tests below.
*/
- (void)png_icc_profile_error(png_ptr, name, temp,
- "unexpected NamedColor ICC profile class");
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unexpected NamedColor ICC profile class");
break;
default:
@@ -1770,8 +2003,8 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
* tag content to ensure they are backward compatible with one of the
* understood profiles.
*/
- (void)png_icc_profile_error(png_ptr, name, temp,
- "unrecognized ICC profile class");
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unrecognized ICC profile class");
break;
}
@@ -1781,21 +2014,21 @@ png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
temp = png_get_uint_32(profile+20);
switch (temp)
{
- case 0x58595a20: /* 'XYZ ' */
- case 0x4c616220: /* 'Lab ' */
+ case 0x58595A20: /* 'XYZ ' */
+ case 0x4C616220: /* 'Lab ' */
break;
default:
- return png_icc_profile_error(png_ptr, name, temp,
- "unexpected ICC PCS encoding");
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected ICC PCS encoding");
}
return 1;
}
int /* PRIVATE */
-png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name,
- png_uint_32 profile_length,
+png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
png_const_bytep profile /* header plus whole tag table */)
{
png_uint_32 tag_count = png_get_uint_32(profile+128);
@@ -1817,151 +2050,316 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name,
* being in range. All defined tag types have an 8 byte header - a 4 byte
* type signature then 0.
*/
+ if ((tag_start & 3) != 0)
+ {
+ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
+ * only a warning here because libpng does not care about the
+ * alignment.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+ "ICC profile tag start not a multiple of 4");
+ }
/* This is a hard error; potentially it can cause read outside the
* profile.
*/
if (tag_start > profile_length || tag_length > profile_length - tag_start)
- return png_icc_profile_error(png_ptr, name, tag_id,
- "ICC profile tag outside profile");
-
- if ((tag_start & 3) != 0)
- {
- /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
- * only a warning here because libpng does not care about the
- * alignment.
- */
- (void)png_icc_profile_error(png_ptr, name, tag_id,
- "ICC profile tag start not a multiple of 4");
- }
+ return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+ "ICC profile tag outside profile");
}
return 1; /* success, maybe with warnings */
}
-#endif /* READ_iCCP */
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-#if (defined PNG_READ_mDCV_SUPPORTED) || (defined PNG_READ_cHRM_SUPPORTED)
+#ifdef PNG_sRGB_SUPPORTED
+/* Information about the known ICC sRGB profiles */
+static const struct
+{
+ png_uint_32 adler, crc, length;
+ png_uint_32 md5[4];
+ png_byte have_md5;
+ png_byte is_broken;
+ png_uint_16 intent;
+
+# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
+# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
+ { adler, crc, length, md5, broke, intent },
+
+} png_sRGB_checks[] =
+{
+ /* This data comes from contrib/tools/checksum-icc run on downloads of
+ * all four ICC sRGB profiles from www.color.org.
+ */
+ /* adler32, crc32, MD5[4], intent, date, length, file-name */
+ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
+ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+
+ /* ICC sRGB v2 perceptual no black-compensation: */
+ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
+ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+
+ PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
+ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+
+ /* ICC sRGB v4 perceptual */
+ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
+ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+
+ /* The following profiles have no known MD5 checksum. If there is a match
+ * on the (empty) MD5 the other fields are used to attempt a match and
+ * a warning is produced. The first two of these profiles have a 'cprt' tag
+ * which suggests that they were also made by Hewlett Packard.
+ */
+ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+
+ /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
+ * match the D50 PCS illuminant in the header (it is in fact the D65 values,
+ * so the white point is recorded as the un-adapted value.) The profiles
+ * below only differ in one byte - the intent - and are basically the same as
+ * the previous profile except for the mediaWhitePointTag error and a missing
+ * chromaticAdaptationTag.
+ */
+ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+
+ PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+};
+
static int
-have_chromaticities(png_const_structrp png_ptr)
+png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
+ png_const_bytep profile, uLong adler)
{
- /* Handle new PNGv3 chunks and the precedence rules to determine whether
- * png_struct::chromaticities must be processed. Only required for RGB to
- * gray.
- *
- * mDCV: this is the mastering colour space and it is independent of the
- * encoding so it needs to be used regardless of the encoded space.
- *
- * cICP: first in priority but not yet implemented - the chromaticities come
- * from the 'primaries'.
- *
- * iCCP: not supported by libpng (so ignored)
- *
- * sRGB: the defaults match sRGB
- *
- * cHRM: calculate the coefficients
+ /* The quick check is to verify just the MD5 signature and trust the
+ * rest of the data. Because the profile has already been verified for
+ * correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
+ * field too, so if the profile has been edited with an intent not defined
+ * by sRGB (but maybe defined by a later ICC specification) the read of
+ * the profile will fail at that point.
*/
-# ifdef PNG_READ_mDCV_SUPPORTED
- if (png_has_chunk(png_ptr, mDCV))
- return 1;
-# define check_chromaticities 1
-# endif /*mDCV*/
+ png_uint_32 length = 0;
+ png_uint_32 intent = 0x10000; /* invalid */
+#if PNG_sRGB_PROFILE_CHECKS > 1
+ uLong crc = 0; /* the value for 0 length data */
+#endif
+ unsigned int i;
-# ifdef PNG_READ_sRGB_SUPPORTED
- if (png_has_chunk(png_ptr, sRGB))
- return 0;
-# endif /*sRGB*/
-
-# ifdef PNG_READ_cHRM_SUPPORTED
- if (png_has_chunk(png_ptr, cHRM))
- return 1;
-# define check_chromaticities 1
-# endif /*cHRM*/
-
- return 0; /* sRGB defaults */
-}
-#endif /* READ_mDCV || READ_cHRM */
-
-void /* PRIVATE */
-png_set_rgb_coefficients(png_structrp png_ptr)
-{
- /* Set the rgb_to_gray coefficients from the colorspace if available. Note
- * that '_set' means that png_rgb_to_gray was called **and** it successfully
- * set up the coefficients.
- */
- if (png_ptr->rgb_to_gray_coefficients_set == 0)
+ for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
{
-# if check_chromaticities
- png_XYZ xyz;
-
- if (have_chromaticities(png_ptr) &&
- png_XYZ_from_xy(&xyz, &png_ptr->chromaticities) == 0)
+ if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
+ png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
+ png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
+ png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
{
- /* png_set_rgb_to_gray has not set the coefficients, get them from the
- * Y * values of the colorspace colorants.
+ /* This may be one of the old HP profiles without an MD5, in that
+ * case we can only use the length and Adler32 (note that these
+ * are not used by default if there is an MD5!)
*/
- png_fixed_point r = xyz.red_Y;
- png_fixed_point g = xyz.green_Y;
- png_fixed_point b = xyz.blue_Y;
- png_fixed_point total = r+g+b;
+# if PNG_sRGB_PROFILE_CHECKS == 0
+ if (png_sRGB_checks[i].have_md5)
+ return 1+png_sRGB_checks[i].is_broken;
+# endif
- if (total > 0 &&
- r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
- g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
- b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
- r+g+b <= 32769)
+ /* Profile is unsigned or more checks have been configured in. */
+ if (length == 0)
{
- /* We allow 0 coefficients here. r+g+b may be 32769 if two or
- * all of the coefficients were rounded up. Handle this by
- * reducing the *largest* coefficient by 1; this matches the
- * approach used for the default coefficients in pngrtran.c
- */
- int add = 0;
+ length = png_get_uint_32(profile);
+ intent = png_get_uint_32(profile+64);
+ }
- if (r+g+b > 32768)
- add = -1;
- else if (r+g+b < 32768)
- add = 1;
-
- if (add != 0)
+ /* Length *and* intent must match */
+ if (length == png_sRGB_checks[i].length &&
+ intent == png_sRGB_checks[i].intent)
+ {
+ /* Now calculate the adler32 if not done already. */
+ if (adler == 0)
{
- if (g >= r && g >= b)
- g += add;
- else if (r >= g && r >= b)
- r += add;
- else
- b += add;
+ adler = adler32(0, NULL, 0);
+ adler = adler32(adler, profile, length);
}
- /* Check for an internal error. */
- if (r+g+b != 32768)
- png_error(png_ptr,
- "internal error handling cHRM coefficients");
-
- else
+ if (adler == png_sRGB_checks[i].adler)
{
- png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
- png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+ /* These basic checks suggest that the data has not been
+ * modified, but if the check level is more than 1 perform
+ * our own crc32 checksum on the data.
+ */
+# if PNG_sRGB_PROFILE_CHECKS > 1
+ if (crc == 0)
+ {
+ crc = crc32(0, NULL, 0);
+ crc = crc32(crc, profile, length);
+ }
+
+ /* So this check must pass for the 'return' below to happen.
+ */
+ if (crc == png_sRGB_checks[i].crc)
+# endif
+ {
+ if (png_sRGB_checks[i].is_broken)
+ {
+ /* These profiles are known to have bad data that may cause
+ * problems if they are used, therefore attempt to
+ * discourage their use, skip the 'have_md5' warning below,
+ * which is made irrelevant by this error.
+ */
+ png_chunk_report(png_ptr, "known incorrect sRGB profile",
+ PNG_CHUNK_ERROR);
+ }
+
+ /* Warn that this being done; this isn't even an error since
+ * the profile is perfectly valid, but it would be nice if
+ * people used the up-to-date ones.
+ */
+ else if (!png_sRGB_checks[i].have_md5)
+ {
+ png_chunk_report(png_ptr,
+ "out-of-date sRGB profile with no signature",
+ PNG_CHUNK_WARNING);
+ }
+
+ return 1+png_sRGB_checks[i].is_broken;
+ }
}
}
- }
- else
-# endif /* check_chromaticities */
- {
- /* Use the historical REC 709 (etc) values: */
- png_ptr->rgb_to_gray_red_coeff = 6968;
- png_ptr->rgb_to_gray_green_coeff = 23434;
- /* png_ptr->rgb_to_gray_blue_coeff = 2366; */
+
+# if PNG_sRGB_PROFILE_CHECKS > 0
+ /* The signature matched, but the profile had been changed in some
+ * way. This is an apparent violation of the ICC terms of use and,
+ * anyway, probably indicates a data error or uninformed hacking.
+ */
+ if (png_sRGB_checks[i].have_md5)
+ png_benign_error(png_ptr,
+ "copyright violation: edited ICC profile ignored");
+# endif
}
}
+
+ return 0; /* no match */
}
-#endif /* READ_RGB_TO_GRAY */
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void /* PRIVATE */
+png_icc_set_sRGB(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+{
+ /* Is this profile one of the known ICC sRGB profiles? If it is, just set
+ * the sRGB information.
+ */
+ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
+ (void)png_colorspace_set_sRGB(png_ptr, colorspace,
+ (int)/*already checked*/png_get_uint_32(profile+64));
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+int /* PRIVATE */
+png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+ int color_type)
+{
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ if (png_icc_check_length(png_ptr, colorspace, name, profile_length) &&
+ png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
+ color_type) &&
+ png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
+ profile))
+ {
+# ifdef PNG_sRGB_SUPPORTED
+ /* If no sRGB support, don't try storing sRGB information */
+ png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
+# endif
+ return 1;
+ }
+
+ /* Failure case */
+ return 0;
+}
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void /* PRIVATE */
+png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
+{
+ /* Set the rgb_to_gray coefficients from the colorspace. */
+ if (!png_ptr->rgb_to_gray_coefficients_set &&
+ (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ /* png_set_background has not been called, get the coefficients from the Y
+ * values of the colorspace colorants.
+ */
+ png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
+ png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
+ png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
+ png_fixed_point total = r+g+b;
+
+ if (total > 0 &&
+ r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
+ g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
+ b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
+ r+g+b <= 32769)
+ {
+ /* We allow 0 coefficients here. r+g+b may be 32769 if two or
+ * all of the coefficients were rounded up. Handle this by
+ * reducing the *largest* coefficient by 1; this matches the
+ * approach used for the default coefficients in pngrtran.c
+ */
+ int add = 0;
+
+ if (r+g+b > 32768)
+ add = -1;
+ else if (r+g+b < 32768)
+ add = 1;
+
+ if (add != 0)
+ {
+ if (g >= r && g >= b)
+ g += add;
+ else if (r >= g && r >= b)
+ r += add;
+ else
+ b += add;
+ }
+
+ /* Check for an internal error. */
+ if (r+g+b != 32768)
+ png_error(png_ptr,
+ "internal error handling cHRM coefficients");
+
+ else
+ {
+ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
+ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+ }
+ }
+
+ /* This is a png_error at present even though it could be ignored -
+ * it should never happen, but it is important that if it does, the
+ * bug is fixed.
+ */
+ else
+ png_error(png_ptr, "internal error handling cHRM->XYZ");
+ }
+}
+#endif
+
+#endif /* COLORSPACE */
void /* PRIVATE */
png_check_IHDR(png_const_structrp png_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth,
- int color_type, int interlace_type, int compression_type,
- int filter_type)
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
{
int error = 0;
@@ -1972,55 +2370,36 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
- if (width > PNG_UINT_31_MAX)
+ if (height == 0)
{
- png_warning(png_ptr, "Invalid image width in IHDR");
+ png_warning(png_ptr, "Image height is zero in IHDR");
error = 1;
}
- /* The bit mask on the first line below must be at least as big as a
- * png_uint_32. "~7U" is not adequate on 16-bit systems because it will
- * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the
- * type of the result at least as bit (in bits) as the RHS of the > operator
- * which also avoids a common warning on 64-bit systems that the comparison
- * of (png_uint_32) against the constant value on the RHS will always be
- * false.
- */
- if (((width + 7) & ~(png_alloc_size_t)7) >
- (((PNG_SIZE_MAX
- - 48 /* big_row_buf hack */
- - 1) /* filter byte */
- / 8) /* 8-byte RGBA pixels */
- - 1)) /* extra max_pixel_depth pad */
- {
- /* The size of the row must be within the limits of this architecture.
- * Because the read code can perform arbitrary transformations the
- * maximum size is checked here. Because the code in png_read_start_row
- * adds extra space "for safety's sake" in several places a conservative
- * limit is used here.
- *
- * NOTE: it would be far better to check the size that is actually used,
- * but the effect in the real world is minor and the changes are more
- * extensive, therefore much more dangerous and much more difficult to
- * write in a way that avoids compiler warnings.
- */
- png_warning(png_ptr, "Image width is too large for this architecture");
- error = 1;
- }
-
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
if (width > png_ptr->user_width_max)
-#else
+
+# else
if (width > PNG_USER_WIDTH_MAX)
-#endif
+# endif
{
png_warning(png_ptr, "Image width exceeds user limit in IHDR");
error = 1;
}
- if (height == 0)
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (height > png_ptr->user_height_max)
+# else
+ if (height > PNG_USER_HEIGHT_MAX)
+# endif
{
- png_warning(png_ptr, "Image height is zero in IHDR");
+ png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+ error = 1;
+ }
+
+ if (width > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image width in IHDR");
error = 1;
}
@@ -2030,15 +2409,13 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED
- if (height > png_ptr->user_height_max)
-#else
- if (height > PNG_USER_HEIGHT_MAX)
-#endif
- {
- png_warning(png_ptr, "Image height exceeds user limit in IHDR");
- error = 1;
- }
+ if (width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 48 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ png_warning(png_ptr, "Width is too large for libpng to process pixels");
/* Check other values */
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
@@ -2076,7 +2453,7 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
-#ifdef PNG_MNG_FEATURES_SUPPORTED
+# ifdef PNG_MNG_FEATURES_SUPPORTED
/* Accept filter_method 64 (intrapixel differencing) only if
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
* 2. Libpng did not read a PNG signature (this filter_method is only
@@ -2086,13 +2463,13 @@ png_check_IHDR(png_const_structrp png_ptr,
* 4. The filter_method is 64 and
* 5. The color_type is RGB or RGBA
*/
- if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
- png_ptr->mng_features_permitted != 0)
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
+ png_ptr->mng_features_permitted)
png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
if (filter_type != PNG_FILTER_TYPE_BASE)
{
- if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
(color_type == PNG_COLOR_TYPE_RGB ||
@@ -2102,20 +2479,20 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
- if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
+ if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
{
png_warning(png_ptr, "Invalid filter method in IHDR");
error = 1;
}
}
-#else
+# else
if (filter_type != PNG_FILTER_TYPE_BASE)
{
png_warning(png_ptr, "Unknown filter method in IHDR");
error = 1;
}
-#endif
+# endif
if (error == 1)
png_error(png_ptr, "Invalid IHDR data");
@@ -2123,7 +2500,7 @@ png_check_IHDR(png_const_structrp png_ptr,
#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
/* ASCII to fp functions */
-/* Check an ASCII formatted floating point value, see the more detailed
+/* Check an ASCII formated floating point value, see the more detailed
* comments in pngpriv.h
*/
/* The following is used internally to preserve the sticky flags */
@@ -2131,11 +2508,11 @@ png_check_IHDR(png_const_structrp png_ptr,
#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
int /* PRIVATE */
-png_check_fp_number(png_const_charp string, size_t size, int *statep,
- size_t *whereami)
+png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
+ png_size_tp whereami)
{
int state = *statep;
- size_t i = *whereami;
+ png_size_t i = *whereami;
while (i < size)
{
@@ -2162,7 +2539,7 @@ png_check_fp_number(png_const_charp string, size_t size, int *statep,
switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
{
case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
- if ((state & PNG_FP_SAW_ANY) != 0)
+ if (state & PNG_FP_SAW_ANY)
goto PNG_FP_End; /* not a part of the number */
png_fp_add(state, type);
@@ -2170,10 +2547,10 @@ png_check_fp_number(png_const_charp string, size_t size, int *statep,
case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
/* Ok as trailer, ok as lead of fraction. */
- if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
+ if (state & PNG_FP_SAW_DOT) /* two dots */
goto PNG_FP_End;
- else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
+ else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */
png_fp_add(state, type);
else
@@ -2182,7 +2559,7 @@ png_check_fp_number(png_const_charp string, size_t size, int *statep,
break;
case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
- if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
+ if (state & PNG_FP_SAW_DOT) /* delayed fraction */
png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
png_fp_add(state, type | PNG_FP_WAS_VALID);
@@ -2220,7 +2597,7 @@ png_check_fp_number(png_const_charp string, size_t size, int *statep,
break;
case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
- if ((state & PNG_FP_SAW_ANY) != 0)
+ if (state & PNG_FP_SAW_ANY)
goto PNG_FP_End; /* not a part of the number */
png_fp_add(state, PNG_FP_SAW_SIGN);
@@ -2258,18 +2635,18 @@ PNG_FP_End:
/* The same but for a complete string. */
int
-png_check_fp_string(png_const_charp string, size_t size)
+png_check_fp_string(png_const_charp string, png_size_t size)
{
- int state = 0;
- size_t char_index = 0;
+ int state=0;
+ png_size_t char_index=0;
- if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
+ if (png_check_fp_number(string, size, &state, &char_index) &&
(char_index == size || string[char_index] == 0))
return state /* must be non-zero - see above */;
return 0; /* i.e. fail */
}
-#endif /* pCAL || sCAL */
+#endif /* pCAL or sCAL */
#ifdef PNG_sCAL_SUPPORTED
# ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -2288,7 +2665,7 @@ png_pow10(int power)
if (power < 0)
{
if (power < DBL_MIN_10_EXP) return 0;
- recip = 1; power = -power;
+ recip = 1, power = -power;
}
if (power > 0)
@@ -2303,7 +2680,7 @@ png_pow10(int power)
}
while (power > 0);
- if (recip != 0) d = 1/d;
+ if (recip) d = 1/d;
}
/* else power is 0 and d is 1 */
@@ -2314,7 +2691,7 @@ png_pow10(int power)
* precision.
*/
void /* PRIVATE */
-png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
double fp, unsigned int precision)
{
/* We use standard functions from math.h, but not printf because
@@ -2341,7 +2718,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
if (fp >= DBL_MIN && fp <= DBL_MAX)
{
- int exp_b10; /* A base 10 exponent */
+ int exp_b10; /* A base 10 exponent */
double base; /* 10^exp_b10 */
/* First extract a base 10 exponent of the number,
@@ -2366,9 +2743,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
double test = png_pow10(exp_b10+1);
if (test <= DBL_MAX)
- {
- ++exp_b10; base = test;
- }
+ ++exp_b10, base = test;
else
break;
@@ -2382,10 +2757,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
* test on DBL_MAX above.
*/
fp /= base;
- while (fp >= 1)
- {
- fp /= 10; ++exp_b10;
- }
+ while (fp >= 1) fp /= 10, ++exp_b10;
/* Because of the code above fp may, at this point, be
* less than .1, this is ok because the code below can
@@ -2394,7 +2766,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
*/
{
- unsigned int czero, clead, cdigits;
+ int czero, clead, cdigits;
char exponent[10];
/* Allow up to two leading zeros - this will not lengthen
@@ -2402,7 +2774,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
*/
if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
{
- czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
+ czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
exp_b10 = 0; /* Dot added below before first output. */
}
else
@@ -2424,7 +2796,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
* of the loop don't break the number into parts so
* that the final digit is rounded.
*/
- if (cdigits+czero+1 < precision+clead)
+ if (cdigits+czero-clead+1 < (int)precision)
fp = modf(fp, &d);
else
@@ -2436,7 +2808,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
/* Rounding up to 10, handle that here. */
if (czero > 0)
{
- --czero; d = 1;
+ --czero, d = 1;
if (cdigits == 0) --clead;
}
else
@@ -2450,7 +2822,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
else if (ch == 46)
{
- ch = *--ascii; ++size;
+ ch = *--ascii, ++size;
/* Advance exp_b10 to '1', so that the
* decimal point happens after the
* previous digit.
@@ -2477,9 +2849,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
int ch = *--ascii;
if (ch == 46)
- {
- ++size; exp_b10 = 1;
- }
+ ++size, exp_b10 = 1;
/* Else lost a leading zero, so 'exp_b10' is
* still ok at (-1)
@@ -2515,49 +2885,43 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
*/
if (exp_b10 != (-1))
{
- if (exp_b10 == 0)
- {
- *ascii++ = 46; --size;
- }
+ if (exp_b10 == 0) *ascii++ = 46, --size;
/* PLUS 1: TOTAL 4 */
--exp_b10;
}
- *ascii++ = 48; --czero;
+ *ascii++ = 48, --czero;
}
if (exp_b10 != (-1))
{
- if (exp_b10 == 0)
- {
- *ascii++ = 46; --size; /* counted above */
- }
-
+ if (exp_b10 == 0) *ascii++ = 46, --size; /* counted
+ above */
--exp_b10;
}
- *ascii++ = (char)(48 + (int)d); ++cdigits;
+ *ascii++ = (char)(48 + (int)d), ++cdigits;
}
}
- while (cdigits+czero < precision+clead && fp > DBL_MIN);
+ while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
/* The total output count (max) is now 4+precision */
/* Check for an exponent, if we don't need one we are
- * done and just need to terminate the string. At this
- * point, exp_b10==(-1) is effectively a flag: it got
- * to '-1' because of the decrement, after outputting
- * the decimal point above. (The exponent required is
- * *not* -1.)
+ * done and just need to terminate the string. At
+ * this point exp_b10==(-1) is effectively if flag - it got
+ * to '-1' because of the decrement after outputing
+ * the decimal point above (the exponent required is
+ * *not* -1!)
*/
if (exp_b10 >= (-1) && exp_b10 <= 2)
{
/* The following only happens if we didn't output the
* leading zeros above for negative exponent, so this
- * doesn't add to the digit requirement. Note that the
+ * doest add to the digit requirement. Note that the
* two zeros here can only be output if the two leading
* zeros were *not* output, so this doesn't increase
* the output count.
*/
- while (exp_b10-- > 0) *ascii++ = 48;
+ while (--exp_b10 >= 0) *ascii++ = 48;
*ascii = 0;
@@ -2575,7 +2939,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
*/
size -= cdigits;
- *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */
+ *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
/* The following use of an unsigned temporary avoids ambiguities in
* the signed arithmetic on exp_b10 and permits GCC at least to do
@@ -2586,12 +2950,12 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
if (exp_b10 < 0)
{
- *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
- uexp_b10 = 0U-exp_b10;
+ *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
+ uexp_b10 = -exp_b10;
}
else
- uexp_b10 = 0U+exp_b10;
+ uexp_b10 = exp_b10;
cdigits = 0;
@@ -2605,7 +2969,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
/* Need another size check here for the exponent digits, so
* this need not be considered above.
*/
- if (size > cdigits)
+ if ((int)size > cdigits)
{
while (cdigits > 0) *ascii++ = exponent[--cdigits];
@@ -2634,6 +2998,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
/* Here on buffer too small. */
png_error(png_ptr, "ASCII conversion buffer too small");
}
+
# endif /* FLOATING_POINT */
# ifdef PNG_FIXED_POINT_SUPPORTED
@@ -2641,7 +3006,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
*/
void /* PRIVATE */
png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
- size_t size, png_fixed_point fp)
+ png_size_t size, png_fixed_point fp)
{
/* Require space for 10 decimal digits, a decimal point, a minus sign and a
* trailing \0, 13 characters:
@@ -2652,16 +3017,14 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
/* Avoid overflow here on the minimum integer. */
if (fp < 0)
- {
- *ascii++ = 45; num = (png_uint_32)(-fp);
- }
+ *ascii++ = 45, --size, num = -fp;
else
- num = (png_uint_32)fp;
+ num = fp;
if (num <= 0x80000000) /* else overflowed */
{
unsigned int ndigits = 0, first = 16 /* flag value */;
- char digits[10] = {0};
+ char digits[10];
while (num)
{
@@ -2692,10 +3055,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
* then ndigits digits to first:
*/
i = 5;
- while (ndigits < i)
- {
- *ascii++ = 48; --i;
- }
+ while (ndigits < i) *ascii++ = 48, --i;
while (ndigits >= first) *ascii++ = digits[--ndigits];
/* Don't output the trailing zeros! */
}
@@ -2713,7 +3073,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
png_error(png_ptr, "ASCII conversion buffer too small");
}
# endif /* FIXED_POINT */
-#endif /* SCAL */
+#endif /* READ_SCAL */
#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
!defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
@@ -2730,35 +3090,11 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
if (r > 2147483647. || r < -2147483648.)
png_fixed_error(png_ptr, text);
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(text)
-# endif
-
return (png_fixed_point)r;
}
#endif
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
- !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
- (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
-png_uint_32
-png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text)
-{
- double r = floor(10000 * fp + .5);
-
- if (r > 2147483647. || r < 0)
- png_fixed_error(png_ptr, text);
-
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(text)
-# endif
-
- return (png_uint_32)r;
-}
-#endif
-
-
-#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
+#if defined(PNG_READ_GAMMA_SUPPORTED) || \
defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
/* muldiv functions */
/* This API takes signed arguments and rounds the result to the nearest
@@ -2766,7 +3102,7 @@ png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text)
* the nearest .00001). Overflow and divide by zero are signalled in
* the result, a boolean - true on success, false on overflow.
*/
-int /* PRIVATE */
+int
png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
png_int_32 divisor)
{
@@ -2863,12 +3199,11 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
if (s00 >= (D >> 1))
++result;
- if (negative != 0)
+ if (negative)
result = -result;
/* Check for overflow. */
- if ((negative != 0 && result <= 0) ||
- (negative == 0 && result >= 0))
+ if ((negative && result <= 0) || (!negative && result >= 0))
{
*res = result;
return 1;
@@ -2880,7 +3215,27 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
return 0;
}
+#endif /* READ_GAMMA || INCH_CONVERSIONS */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* The following is for when the caller doesn't much care about the
+ * result.
+ */
+png_fixed_point
+png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
+ png_int_32 divisor)
+{
+ png_fixed_point result;
+
+ if (png_muldiv(&result, a, times, divisor))
+ return result;
+
+ png_warning(png_ptr, "fixed point overflow ignored");
+ return 0;
+}
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
png_fixed_point
png_reciprocal(png_fixed_point a)
@@ -2893,44 +3248,31 @@ png_reciprocal(png_fixed_point a)
#else
png_fixed_point res;
- if (png_muldiv(&res, 100000, 100000, a) != 0)
+ if (png_muldiv(&res, 100000, 100000, a))
return res;
#endif
return 0; /* error/overflow */
}
-#endif /* READ_GAMMA || COLORSPACE || INCH_CONVERSIONS || READ_pHYS */
-#ifdef PNG_READ_GAMMA_SUPPORTED
/* This is the shared test on whether a gamma value is 'significant' - whether
* it is worth doing gamma correction.
*/
int /* PRIVATE */
png_gamma_significant(png_fixed_point gamma_val)
{
- /* sRGB: 1/2.2 == 0.4545(45)
- * AdobeRGB: 1/(2+51/256) ~= 0.45471 5dp
- *
- * So the correction from AdobeRGB to sRGB (output) is:
- *
- * 2.2/(2+51/256) == 1.00035524
- *
- * I.e. vanishly small (<4E-4) but still detectable in 16-bit linear (+/-
- * 23). Note that the Adobe choice seems to be something intended to give an
- * exact number with 8 binary fractional digits - it is the closest to 2.2
- * that is possible a base 2 .8p representation.
- */
return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
}
+#endif
-#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
/* A local convenience routine. */
static png_fixed_point
png_product2(png_fixed_point a, png_fixed_point b)
{
- /* The required result is a * b; the following preserves accuracy. */
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Should now be unused */
+ /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
double r = a * 1E-5;
r *= b;
r = floor(r+.5);
@@ -2940,28 +3282,25 @@ png_product2(png_fixed_point a, png_fixed_point b)
#else
png_fixed_point res;
- if (png_muldiv(&res, a, b, 100000) != 0)
+ if (png_muldiv(&res, a, b, 100000))
return res;
#endif
return 0; /* overflow */
}
-#endif /* FLOATING_ARITHMETIC */
+/* The inverse of the above. */
png_fixed_point
png_reciprocal2(png_fixed_point a, png_fixed_point b)
{
/* The required result is 1/a * 1/b; the following preserves accuracy. */
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- if (a != 0 && b != 0)
- {
- double r = 1E15/a;
- r /= b;
- r = floor(r+.5);
+ double r = 1E15/a;
+ r /= b;
+ r = floor(r+.5);
- if (r <= 2147483647. && r >= -2147483648.)
- return (png_fixed_point)r;
- }
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
#else
/* This may overflow because the range of png_fixed_point isn't symmetric,
* but this API is only used for the product of file and screen gamma so it
@@ -3100,7 +3439,6 @@ png_log8bit(unsigned int x)
* Zero (257): 0
* End (258): 23499
*/
-#ifdef PNG_16BIT_SUPPORTED
static png_int_32
png_log16bit(png_uint_32 x)
{
@@ -3151,20 +3489,19 @@ png_log16bit(png_uint_32 x)
/* Safe, because the result can't have more than 20 bits: */
return (png_int_32)((lg2 + 2048) >> 12);
}
-#endif /* 16BIT */
/* The 'exp()' case must invert the above, taking a 20-bit fixed point
* logarithmic value and returning a 16 or 8-bit number as appropriate. In
* each case only the low 16 bits are relevant - the fraction - since the
* integer bits (the top 4) simply determine a shift.
*
- * The worst case is the 16-bit distinction between 65535 and 65534. This
- * requires perhaps spurious accuracy in the decoding of the logarithm to
+ * The worst case is the 16-bit distinction between 65535 and 65534, this
+ * requires perhaps spurious accuracty in the decoding of the logarithm to
* distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance
* of getting this accuracy in practice.
*
* To deal with this the following exp() function works out the exponent of the
- * fractional part of the logarithm by using an accurate 32-bit value from the
+ * frational part of the logarithm by using an accurate 32-bit value from the
* top four fractional bits then multiplying in the remaining bits.
*/
static const png_uint_32
@@ -3199,7 +3536,7 @@ png_exp(png_fixed_point x)
if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
{
/* Obtain a 4-bit approximation */
- png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
+ png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
/* Incorporate the low 12 bits - these decrease the returned value by
* multiplying by a number less than 1 if the bit is set. The multiplier
@@ -3247,15 +3584,14 @@ png_exp8bit(png_fixed_point lg2)
/* Get a 32-bit value: */
png_uint_32 x = png_exp(lg2);
- /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
+ /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the
* second, rounding, step can't overflow because of the first, subtraction,
* step.
*/
x -= x >> 8;
- return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
+ return (png_byte)((x + 0x7fffffU) >> 24);
}
-#ifdef PNG_16BIT_SUPPORTED
static png_uint_16
png_exp16bit(png_fixed_point lg2)
{
@@ -3266,7 +3602,6 @@ png_exp16bit(png_fixed_point lg2)
x -= x >> 16;
return (png_uint_16)((x + 32767U) >> 16);
}
-#endif /* 16BIT */
#endif /* FLOATING_ARITHMETIC */
png_byte
@@ -3275,37 +3610,13 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
if (value > 0 && value < 255)
{
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
- * convert this to a floating point value. This includes values that
- * would overflow if 'value' were to be converted to 'int'.
- *
- * Apparently GCC, however, does an intermediate conversion to (int)
- * on some (ARM) but not all (x86) platforms, possibly because of
- * hardware FP limitations. (E.g. if the hardware conversion always
- * assumes the integer register contains a signed value.) This results
- * in ANSI-C undefined behavior for large values.
- *
- * Other implementations on the same machine might actually be ANSI-C90
- * conformant and therefore compile spurious extra code for the large
- * values.
- *
- * We can be reasonably sure that an unsigned to float conversion
- * won't be faster than an int to float one. Therefore this code
- * assumes responsibility for the undefined behavior, which it knows
- * can't happen because of the check above.
- *
- * Note the argument to this routine is an (unsigned int) because, on
- * 16-bit platforms, it is assigned a value which might be out of
- * range for an (int); that would result in undefined behavior in the
- * caller if the *argument* ('value') were to be declared (int).
- */
- double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
+ double r = floor(255*pow(value/255.,gamma_val*.00001)+.5);
return (png_byte)r;
# else
png_int_32 lg2 = png_log8bit(value);
png_fixed_point res;
- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
return png_exp8bit(res);
/* Overflow. */
@@ -3313,39 +3624,31 @@ png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
# endif
}
- return (png_byte)(value & 0xff);
+ return (png_byte)value;
}
-#ifdef PNG_16BIT_SUPPORTED
png_uint_16
png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
{
if (value > 0 && value < 65535)
{
-# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- /* The same (unsigned int)->(double) constraints apply here as above,
- * however in this case the (unsigned int) to (int) conversion can
- * overflow on an ANSI-C90 compliant system so the cast needs to ensure
- * that this is not possible.
- */
- double r = floor(65535*pow((png_int_32)value/65535.,
- gamma_val*.00001)+.5);
- return (png_uint_16)r;
-# else
- png_int_32 lg2 = png_log16bit(value);
- png_fixed_point res;
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
+ return (png_uint_16)r;
+# else
+ png_int_32 lg2 = png_log16bit(value);
+ png_fixed_point res;
- if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
- return png_exp16bit(res);
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
+ return png_exp16bit(res);
- /* Overflow. */
- value = 0;
-# endif
+ /* Overflow. */
+ value = 0;
+# endif
}
return (png_uint_16)value;
}
-#endif /* 16BIT */
/* This does the right thing based on the bit_depth field of the
* png_struct, interpreting values as 8-bit or 16-bit. While the result
@@ -3359,16 +3662,10 @@ png_gamma_correct(png_structrp png_ptr, unsigned int value,
if (png_ptr->bit_depth == 8)
return png_gamma_8bit_correct(value, gamma_val);
-#ifdef PNG_16BIT_SUPPORTED
else
return png_gamma_16bit_correct(value, gamma_val);
-#else
- /* should not reach this */
- return 0;
-#endif /* 16BIT */
}
-#ifdef PNG_16BIT_SUPPORTED
/* Internal function to build a single 16-bit table - the table consists of
* 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
* to shift the input values right (or 16-number_of_signifiant_bits).
@@ -3379,18 +3676,12 @@ png_gamma_correct(png_structrp png_ptr, unsigned int value,
*/
static void
png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
- unsigned int shift, png_fixed_point gamma_val)
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
{
/* Various values derived from 'shift': */
- unsigned int num = 1U << (8U - shift);
-#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- /* CSE the division and work round wacky GCC warnings (see the comments
- * in png_gamma_8bit_correct for where these come from.)
- */
- double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1);
-#endif
- unsigned int max = (1U << (16U - shift)) - 1U;
- unsigned int max_by_2 = 1U << (15U - shift);
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+ PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
unsigned int i;
png_uint_16pp table = *ptable =
@@ -3404,7 +3695,7 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
/* The 'threshold' test is repeated here because it can arise for one of
* the 16-bit tables even if the others don't hit it.
*/
- if (png_gamma_significant(gamma_val) != 0)
+ if (png_gamma_significant(gamma_val))
{
/* The old code would overflow at the end and this would cause the
* 'pow' function to return a result >1, resulting in an
@@ -3420,13 +3711,10 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
png_uint_32 ig = (j << (8-shift)) + i;
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
/* Inline the 'max' scaling operation: */
- /* See png_gamma_8bit_correct for why the cast to (int) is
- * required here.
- */
- double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
+ double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5);
sub_table[j] = (png_uint_16)d;
# else
- if (shift != 0)
+ if (shift)
ig = (ig * 65535U + max_by_2)/max;
sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
@@ -3442,7 +3730,7 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
{
png_uint_32 ig = (j << (8-shift)) + i;
- if (shift != 0)
+ if (shift)
ig = (ig * 65535U + max_by_2)/max;
sub_table[j] = (png_uint_16)ig;
@@ -3456,10 +3744,10 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
*/
static void
png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
- unsigned int shift, png_fixed_point gamma_val)
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
{
- unsigned int num = 1U << (8U - shift);
- unsigned int max = (1U << (16U - shift))-1U;
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
unsigned int i;
png_uint_32 last;
@@ -3468,7 +3756,7 @@ png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
/* 'num' is the number of tables and also the number of low bits of low
* bits of the input 16-bit value used to select a table. Each table is
- * itself indexed by the high 8 bits of the value.
+ * itself index by the high 8 bits of the value.
*/
for (i = 0; i < num; i++)
table[i] = (png_uint_16p)png_malloc(png_ptr,
@@ -3516,26 +3804,23 @@ png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
last++;
}
}
-#endif /* 16BIT */
/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
* typically much faster). Note that libpng currently does no sBIT processing
- * (apparently contrary to the spec) so a 256-entry table is always generated.
+ * (apparently contrary to the spec) so a 256 entry table is always generated.
*/
static void
png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
- png_fixed_point gamma_val)
+ PNG_CONST png_fixed_point gamma_val)
{
unsigned int i;
png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
- if (png_gamma_significant(gamma_val) != 0)
- for (i=0; i<256; i++)
- table[i] = png_gamma_8bit_correct(i, gamma_val);
+ if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++)
+ table[i] = png_gamma_8bit_correct(i, gamma_val);
- else
- for (i=0; i<256; ++i)
- table[i] = (png_byte)(i & 0xff);
+ else for (i=0; i<256; ++i)
+ table[i] = (png_byte)i;
}
/* Used from png_read_destroy and below to release the memory used by the gamma
@@ -3547,7 +3832,6 @@ png_destroy_gamma_table(png_structrp png_ptr)
png_free(png_ptr, png_ptr->gamma_table);
png_ptr->gamma_table = NULL;
-#ifdef PNG_16BIT_SUPPORTED
if (png_ptr->gamma_16_table != NULL)
{
int i;
@@ -3559,7 +3843,6 @@ png_destroy_gamma_table(png_structrp png_ptr)
png_free(png_ptr, png_ptr->gamma_16_table);
png_ptr->gamma_16_table = NULL;
}
-#endif /* 16BIT */
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
@@ -3569,7 +3852,6 @@ png_destroy_gamma_table(png_structrp png_ptr)
png_free(png_ptr, png_ptr->gamma_to_1);
png_ptr->gamma_to_1 = NULL;
-#ifdef PNG_16BIT_SUPPORTED
if (png_ptr->gamma_16_from_1 != NULL)
{
int i;
@@ -3592,7 +3874,6 @@ png_destroy_gamma_table(png_structrp png_ptr)
png_free(png_ptr, png_ptr->gamma_16_to_1);
png_ptr->gamma_16_to_1 = NULL;
}
-#endif /* 16BIT */
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
}
@@ -3600,170 +3881,141 @@ png_destroy_gamma_table(png_structrp png_ptr)
* tables, we don't make a full table if we are reducing to 8-bit in
* the future. Note also how the gamma_16 tables are segmented so that
* we don't need to allocate > 64K chunks for a full 16-bit table.
- *
- * TODO: move this to pngrtran.c and make it static. Better yet create
- * pngcolor.c and put all the PNG_COLORSPACE stuff in there.
*/
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
- defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-# define GAMMA_TRANSFORMS 1 /* #ifdef CSE */
-#else
-# define GAMMA_TRANSFORMS 0
-#endif
-
void /* PRIVATE */
png_build_gamma_table(png_structrp png_ptr, int bit_depth)
{
- png_fixed_point file_gamma, screen_gamma;
- png_fixed_point correction;
-# if GAMMA_TRANSFORMS
- png_fixed_point file_to_linear, linear_to_screen;
-# endif
+ png_debug(1, "in png_build_gamma_table");
- png_debug(1, "in png_build_gamma_table");
+ /* Remove any existing table; this copes with multiple calls to
+ * png_read_update_info. The warning is because building the gamma tables
+ * multiple times is a performance hit - it's harmless but the ability to call
+ * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
+ * to warn if the app introduces such a hit.
+ */
+ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+ {
+ png_warning(png_ptr, "gamma table being rebuilt");
+ png_destroy_gamma_table(png_ptr);
+ }
- /* Remove any existing table; this copes with multiple calls to
- * png_read_update_info. The warning is because building the gamma tables
- * multiple times is a performance hit - it's harmless but the ability to
- * call png_read_update_info() multiple times is new in 1.5.6 so it seems
- * sensible to warn if the app introduces such a hit.
- */
- if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
- {
- png_warning(png_ptr, "gamma table being rebuilt");
- png_destroy_gamma_table(png_ptr);
- }
+ if (bit_depth <= 8)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
- /* The following fields are set, finally, in png_init_read_transformations.
- * If file_gamma is 0 (unset) nothing can be done otherwise if screen_gamma
- * is 0 (unset) there is no gamma correction but to/from linear is possible.
- */
- file_gamma = png_ptr->file_gamma;
- screen_gamma = png_ptr->screen_gamma;
-# if GAMMA_TRANSFORMS
- file_to_linear = png_reciprocal(file_gamma);
-# endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+ png_reciprocal(png_ptr->colorspace.gamma));
- if (screen_gamma > 0)
- {
-# if GAMMA_TRANSFORMS
- linear_to_screen = png_reciprocal(screen_gamma);
-# endif
- correction = png_reciprocal2(screen_gamma, file_gamma);
- }
- else /* screen gamma unknown */
- {
-# if GAMMA_TRANSFORMS
- linear_to_screen = file_gamma;
-# endif
- correction = PNG_FP_1;
- }
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
+ else
+ {
+ png_byte shift, sig_bit;
- if (bit_depth <= 8)
- {
- png_build_8bit_table(png_ptr, &png_ptr->gamma_table, correction);
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit = png_ptr->sig_bit.red;
-#if GAMMA_TRANSFORMS
- if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
- {
- png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, file_to_linear);
+ if (png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+
+ if (png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ sig_bit = png_ptr->sig_bit.gray;
+
+ /* 16-bit gamma code uses this equation:
+ *
+ * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+ *
+ * Where 'iv' is the input color value and 'ov' is the output value -
+ * pow(iv, gamma).
+ *
+ * Thus the gamma table consists of up to 256 256 entry tables. The table
+ * is selected by the (8-gamma_shift) most significant of the low 8 bits of
+ * the color value then indexed by the upper 8 bits:
+ *
+ * table[low bits][high 8 bits]
+ *
+ * So the table 'n' corresponds to all those 'iv' of:
+ *
+ * ..<(n+1 << gamma_shift)-1>
+ *
+ */
+ if (sig_bit > 0 && sig_bit < 16U)
+ shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
+
+ else
+ shift = 0; /* keep all 16 bits */
+
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
+ {
+ /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+ * the significant bits in the *input* when the output will
+ * eventually be 8 bits. By default it is 11.
+ */
+ if (shift < (16U - PNG_MAX_GAMMA_8))
+ shift = (16U - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8U)
+ shift = 8U; /* Guarantees at least one table! */
+
+ png_ptr->gamma_shift = shift;
- png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
- linear_to_screen);
- }
-#endif /* GAMMA_TRANSFORMS */
- }
#ifdef PNG_16BIT_SUPPORTED
- else
- {
- png_byte shift, sig_bit;
-
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
- {
- sig_bit = png_ptr->sig_bit.red;
-
- if (png_ptr->sig_bit.green > sig_bit)
- sig_bit = png_ptr->sig_bit.green;
-
- if (png_ptr->sig_bit.blue > sig_bit)
- sig_bit = png_ptr->sig_bit.blue;
- }
- else
- sig_bit = png_ptr->sig_bit.gray;
-
- /* 16-bit gamma code uses this equation:
- *
- * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
- *
- * Where 'iv' is the input color value and 'ov' is the output value -
- * pow(iv, gamma).
- *
- * Thus the gamma table consists of up to 256 256-entry tables. The table
- * is selected by the (8-gamma_shift) most significant of the low 8 bits
- * of the color value then indexed by the upper 8 bits:
- *
- * table[low bits][high 8 bits]
- *
- * So the table 'n' corresponds to all those 'iv' of:
- *
- * ..<(n+1 << gamma_shift)-1>
- *
- */
- if (sig_bit > 0 && sig_bit < 16U)
- /* shift == insignificant bits */
- shift = (png_byte)((16U - sig_bit) & 0xff);
-
- else
- shift = 0; /* keep all 16 bits */
-
- if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
- {
- /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
- * the significant bits in the *input* when the output will
- * eventually be 8 bits. By default it is 11.
- */
- if (shift < (16U - PNG_MAX_GAMMA_8))
- shift = (16U - PNG_MAX_GAMMA_8);
- }
-
- if (shift > 8U)
- shift = 8U; /* Guarantees at least one table! */
-
- png_ptr->gamma_shift = shift;
-
- /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
- * PNG_COMPOSE). This effectively smashed the background calculation for
- * 16-bit output because the 8-bit table assumes the result will be
- * reduced to 8 bits.
- */
- if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+ /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+ * PNG_COMPOSE). This effectively smashed the background calculation for
+ * 16-bit output because the 8-bit table assumes the result will be reduced
+ * to 8 bits.
+ */
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
+#endif
png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
- png_reciprocal(correction));
- else
+ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+#ifdef PNG_16BIT_SUPPORTED
+ else
png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
- correction);
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+#endif
-# if GAMMA_TRANSFORMS
- if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
- {
- png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
- file_to_linear);
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
+ {
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+ png_reciprocal(png_ptr->colorspace.gamma));
- /* Notice that the '16 from 1' table should be full precision, however
- * the lookup on this table still uses gamma_shift, so it can't be.
- * TODO: fix this.
- */
- png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
- linear_to_screen);
- }
-#endif /* GAMMA_TRANSFORMS */
- }
-#endif /* 16BIT */
+ /* Notice that the '16 from 1' table should be full precision, however
+ * the lookup on this table still uses gamma_shift, so it can't be.
+ * TODO: fix this.
+ */
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
}
#endif /* READ_GAMMA */
-/* HARDWARE OR SOFTWARE OPTION SUPPORT */
+/* HARDWARE OPTION SUPPORT */
#ifdef PNG_SET_OPTION_SUPPORTED
int PNGAPI
png_set_option(png_structrp png_ptr, int option, int onoff)
@@ -3771,13 +4023,13 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
(option & 1) == 0)
{
- png_uint_32 mask = 3U << option;
- png_uint_32 setting = (2U + (onoff != 0)) << option;
- png_uint_32 current = png_ptr->options;
+ int mask = 3 << option;
+ int setting = (2 + (onoff != 0)) << option;
+ int current = png_ptr->options;
- png_ptr->options = (png_uint_32)((current & ~mask) | setting);
+ png_ptr->options = (png_byte)((current & ~mask) | setting);
- return (int)(current & mask) >> option;
+ return (current & mask) >> option;
}
return PNG_OPTION_INVALID;
@@ -3789,9 +4041,9 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
/* sRGB conversion tables; these are machine generated with the code in
* contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the
- * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
+ * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
* is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
- * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
+ * The sRGB to linear table is exact (to the nearest 16 bit linear fraction).
* The inverse (linear to sRGB) table has accuracies as follows:
*
* For all possible (255*65535+1) input values:
@@ -3802,7 +4054,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
*
* error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
*
- * In all cases the inexact readings are only off by one.
+ * In all cases the inexact readings are off by one.
*/
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
@@ -3842,7 +4094,8 @@ const png_uint_16 png_sRGB_table[256] =
57105,57646,58190,58737,59287,59840,60396,60955,
61517,62082,62650,63221,63795,64372,64952,65535
};
-#endif /* SIMPLIFIED_READ */
+
+#endif /* simplified read only */
/* The base/delta tables are required for both read and write (but currently
* only the simplified versions.)
@@ -3970,9 +4223,9 @@ png_image_free_function(png_voidp argument)
/* First free any data held in the control structure. */
# ifdef PNG_STDIO_SUPPORTED
- if (cp->owned_file != 0)
+ if (cp->owned_file)
{
- FILE *fp = png_voidcast(FILE *, cp->png_ptr->io_ptr);
+ FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
cp->owned_file = 0;
/* Ignore errors here. */
@@ -3994,7 +4247,7 @@ png_image_free_function(png_voidp argument)
png_free(c.png_ptr, cp);
/* Then the structures, calling the correct API. */
- if (c.for_write != 0)
+ if (c.for_write)
{
# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
@@ -4025,7 +4278,8 @@ png_image_free(png_imagep image)
if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL)
{
- png_image_free_function(image);
+ /* Ignore errors here: */
+ (void)png_safe_execute(image, png_image_free_function, image);
image->opaque = NULL;
}
}
@@ -4041,4 +4295,4 @@ png_image_error(png_imagep image, png_const_charp error_message)
}
#endif /* SIMPLIFIED READ/WRITE */
-#endif /* READ || WRITE */
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
diff --git a/Windows_Libs/Dev/Render/libpng/png.h b/Windows_Libs/Dev/Render/libpng/png.h
index 38fd349..68a0772 100644
--- a/Windows_Libs/Dev/Render/libpng/png.h
+++ b/Windows_Libs/Dev/Render/libpng/png.h
@@ -1,197 +1,26 @@
+
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.55
+ * libpng version 1.6.2 - April 25, 2013
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * This code is released under the libpng license. (See LICENSE, below.)
+ * This code is released under the libpng license (See LICENSE, below)
*
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
- * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.6.35, July 2018:
- * Glenn Randers-Pehrson
- * libpng versions 1.6.36, December 2018, through 1.6.55, February 2026:
- * Cosmin Truta
+ * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.6.2 - April 25, 2013: Glenn
* See also "Contributing Authors", below.
- */
-
-/*
- * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
- * =========================================
*
- * PNG Reference Library License version 2
- * ---------------------------------------
+ * Note about libpng version numbers:
*
- * * Copyright (c) 1995-2026 The PNG Reference Library Authors.
- * * Copyright (c) 2018-2026 Cosmin Truta.
- * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
- * * Copyright (c) 1996-1997 Andreas Dilger.
- * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * The software is supplied "as is", without warranty of any kind,
- * express or implied, including, without limitation, the warranties
- * of merchantability, fitness for a particular purpose, title, and
- * non-infringement. In no event shall the Copyright owners, or
- * anyone distributing the software, be liable for any damages or
- * other liability, whether in contract, tort or otherwise, arising
- * from, out of, or in connection with the software, or the use or
- * other dealings in the software, even if advised of the possibility
- * of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute
- * this software, or portions hereof, for any purpose, without fee,
- * subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you
- * must not claim that you wrote the original software. If you
- * use this software in a product, an acknowledgment in the product
- * documentation would be appreciated, but is not required.
- *
- * 2. Altered source versions must be plainly marked as such, and must
- * not be misrepresented as being the original software.
- *
- * 3. This Copyright notice may not be removed or altered from any
- * source or altered source distribution.
- *
- *
- * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
- * -----------------------------------------------------------------------
- *
- * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
- * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
- * derived from libpng-1.0.6, and are distributed according to the same
- * disclaimer and license as libpng-1.0.6 with the following individuals
- * added to the list of Contributing Authors:
- *
- * Simon-Pierre Cadieux
- * Eric S. Raymond
- * Mans Rullgard
- * Cosmin Truta
- * Gilles Vollant
- * James Yu
- * Mandar Sahastrabuddhe
- * Google Inc.
- * Vadim Barkov
- *
- * and with the following additions to the disclaimer:
- *
- * There is no warranty against interference with your enjoyment of
- * the library or against infringement. There is no warranty that our
- * efforts or the library will fulfill any of your particular purposes
- * or needs. This library is provided with all faults, and the entire
- * risk of satisfactory quality, performance, accuracy, and effort is
- * with the user.
- *
- * Some files in the "contrib" directory and some configure-generated
- * files that are distributed with libpng have other copyright owners, and
- * are released under other open source licenses.
- *
- * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
- * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
- * libpng-0.96, and are distributed according to the same disclaimer and
- * license as libpng-0.96, with the following individuals added to the
- * list of Contributing Authors:
- *
- * Tom Lane
- * Glenn Randers-Pehrson
- * Willem van Schaik
- *
- * libpng versions 0.89, June 1996, through 0.96, May 1997, are
- * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
- * and are distributed according to the same disclaimer and license as
- * libpng-0.88, with the following individuals added to the list of
- * Contributing Authors:
- *
- * John Bowler
- * Kevin Bracey
- * Sam Bushell
- * Magnus Holmgren
- * Greg Roelofs
- * Tom Tanner
- *
- * Some files in the "scripts" directory have other copyright owners,
- * but are released under this license.
- *
- * libpng versions 0.5, May 1995, through 0.88, January 1996, are
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
- *
- * For the purposes of this copyright and license, "Contributing Authors"
- * is defined as the following set of individuals:
- *
- * Andreas Dilger
- * Dave Martindale
- * Guy Eric Schalnat
- * Paul Schmidt
- * Tim Wegner
- *
- * The PNG Reference Library is supplied "AS IS". The Contributing
- * Authors and Group 42, Inc. disclaim all warranties, expressed or
- * implied, including, without limitation, the warranties of
- * merchantability and of fitness for any purpose. The Contributing
- * Authors and Group 42, Inc. assume no liability for direct, indirect,
- * incidental, special, exemplary, or consequential damages, which may
- * result from the use of the PNG Reference Library, even if advised of
- * the possibility of such damage.
- *
- * Permission is hereby granted to use, copy, modify, and distribute this
- * source code, or portions hereof, for any purpose, without fee, subject
- * to the following restrictions:
- *
- * 1. The origin of this source code must not be misrepresented.
- *
- * 2. Altered versions must be plainly marked as such and must not
- * be misrepresented as being the original source.
- *
- * 3. This Copyright notice may not be removed or altered from any
- * source or altered source distribution.
- *
- * The Contributing Authors and Group 42, Inc. specifically permit,
- * without fee, and encourage the use of this source code as a component
- * to supporting the PNG file format in commercial products. If you use
- * this source code in a product, acknowledgment is not required but would
- * be appreciated.
- *
- * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
- *
- * TRADEMARK
- * =========
- *
- * The name "libpng" has not been registered by the Copyright owners
- * as a trademark in any jurisdiction. However, because libpng has
- * been distributed and maintained world-wide, continually since 1995,
- * the Copyright owners claim "common-law trademark protection" in any
- * jurisdiction where common-law trademark is recognized.
- */
-
-/*
- * A "png_get_copyright" function is available, for convenient use in "about"
- * boxes and the like:
- *
- * printf("%s", png_get_copyright(NULL));
- *
- * Also, the PNG logo (in PNG format, of course) is supplied in the
- * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
- */
-
-/*
- * The contributing authors would like to thank all those who helped
- * with testing, bug fixes, and patience. This wouldn't have been
- * possible without all of you.
- *
- * Thanks to Frank J. T. Wojcik for helping with the documentation.
- */
-
-/* Note about libpng version numbers:
- *
- * Due to various miscommunications, unforeseen code incompatibilities
- * and occasional factors outside the authors' control, version numbering
- * on the library has not always been consistent and straightforward.
- * The following table summarizes matters since version 0.89c, which was
- * the first widely used release:
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
*
* source png.h png.h shared-lib
* version string int version
@@ -229,34 +58,317 @@
* 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
* 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
* 1.0.7 1 10007 (still compatible)
- * ...
- * 1.0.69 10 10069 10.so.0.69[.0]
- * ...
- * 1.2.59 13 10259 12.so.0.59[.0]
- * ...
- * 1.4.20 14 10420 14.so.0.20[.0]
- * ...
- * 1.5.30 15 10530 15.so.15.30[.0]
- * ...
- * 1.6.55 16 10655 16.so.16.55[.0]
+ * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ * 1.0.8rc1 1 10008 2.1.0.8rc1
+ * 1.0.8 1 10008 2.1.0.8
+ * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ * 1.0.9rc1 1 10009 2.1.0.9rc1
+ * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ * 1.0.9rc2 1 10009 2.1.0.9rc2
+ * 1.0.9 1 10009 2.1.0.9
+ * 1.0.10beta1 1 10010 2.1.0.10beta1
+ * 1.0.10rc1 1 10010 2.1.0.10rc1
+ * 1.0.10 1 10010 2.1.0.10
+ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ * 1.0.11rc1 1 10011 2.1.0.11rc1
+ * 1.0.11 1 10011 2.1.0.11
+ * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ * 1.0.12rc1 2 10012 2.1.0.12rc1
+ * 1.0.12 2 10012 2.1.0.12
+ * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
+ * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ * 1.2.0rc1 3 10200 3.1.2.0rc1
+ * 1.2.0 3 10200 3.1.2.0
+ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
+ * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ * 1.2.1 3 10201 3.1.2.1
+ * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ * 1.0.13 10 10013 10.so.0.1.0.13
+ * 1.2.2 12 10202 12.so.0.1.2.2
+ * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ * 1.2.3 12 10203 12.so.0.1.2.3
+ * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
+ * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ * 1.0.14 10 10014 10.so.0.1.0.14
+ * 1.2.4 13 10204 12.so.0.1.2.4
+ * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
+ * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ * 1.0.15 10 10015 10.so.0.1.0.15
+ * 1.2.5 13 10205 12.so.0.1.2.5
+ * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
+ * 1.0.16 10 10016 10.so.0.1.0.16
+ * 1.2.6 13 10206 12.so.0.1.2.6
+ * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
+ * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1
+ * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
+ * 1.0.17 10 10017 12.so.0.1.0.17
+ * 1.2.7 13 10207 12.so.0.1.2.7
+ * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
+ * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5
+ * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
+ * 1.0.18 10 10018 12.so.0.1.0.18
+ * 1.2.8 13 10208 12.so.0.1.2.8
+ * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
+ * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
+ * 1.2.9rc1 13 10209 12.so.0.9[.0]
+ * 1.2.9 13 10209 12.so.0.9[.0]
+ * 1.2.10beta1-7 13 10210 12.so.0.10[.0]
+ * 1.2.10rc1-2 13 10210 12.so.0.10[.0]
+ * 1.2.10 13 10210 12.so.0.10[.0]
+ * 1.4.0beta1-5 14 10400 14.so.0.0[.0]
+ * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
+ * 1.4.0beta7-8 14 10400 14.so.0.0[.0]
+ * 1.2.11 13 10211 12.so.0.11[.0]
+ * 1.2.12 13 10212 12.so.0.12[.0]
+ * 1.4.0beta9-14 14 10400 14.so.0.0[.0]
+ * 1.2.13 13 10213 12.so.0.13[.0]
+ * 1.4.0beta15-36 14 10400 14.so.0.0[.0]
+ * 1.4.0beta37-87 14 10400 14.so.14.0[.0]
+ * 1.4.0rc01 14 10400 14.so.14.0[.0]
+ * 1.4.0beta88-109 14 10400 14.so.14.0[.0]
+ * 1.4.0rc02-08 14 10400 14.so.14.0[.0]
+ * 1.4.0 14 10400 14.so.14.0[.0]
+ * 1.4.1beta01-03 14 10401 14.so.14.1[.0]
+ * 1.4.1rc01 14 10401 14.so.14.1[.0]
+ * 1.4.1beta04-12 14 10401 14.so.14.1[.0]
+ * 1.4.1 14 10401 14.so.14.1[.0]
+ * 1.4.2 14 10402 14.so.14.2[.0]
+ * 1.4.3 14 10403 14.so.14.3[.0]
+ * 1.4.4 14 10404 14.so.14.4[.0]
+ * 1.5.0beta01-58 15 10500 15.so.15.0[.0]
+ * 1.5.0rc01-07 15 10500 15.so.15.0[.0]
+ * 1.5.0 15 10500 15.so.15.0[.0]
+ * 1.5.1beta01-11 15 10501 15.so.15.1[.0]
+ * 1.5.1rc01-02 15 10501 15.so.15.1[.0]
+ * 1.5.1 15 10501 15.so.15.1[.0]
+ * 1.5.2beta01-03 15 10502 15.so.15.2[.0]
+ * 1.5.2rc01-03 15 10502 15.so.15.2[.0]
+ * 1.5.2 15 10502 15.so.15.2[.0]
+ * 1.5.3beta01-10 15 10503 15.so.15.3[.0]
+ * 1.5.3rc01-02 15 10503 15.so.15.3[.0]
+ * 1.5.3beta11 15 10503 15.so.15.3[.0]
+ * 1.5.3 [omitted]
+ * 1.5.4beta01-08 15 10504 15.so.15.4[.0]
+ * 1.5.4rc01 15 10504 15.so.15.4[.0]
+ * 1.5.4 15 10504 15.so.15.4[.0]
+ * 1.5.5beta01-08 15 10505 15.so.15.5[.0]
+ * 1.5.5rc01 15 10505 15.so.15.5[.0]
+ * 1.5.5 15 10505 15.so.15.5[.0]
+ * 1.5.6beta01-07 15 10506 15.so.15.6[.0]
+ * 1.5.6rc01-03 15 10506 15.so.15.6[.0]
+ * 1.5.6 15 10506 15.so.15.6[.0]
+ * 1.5.7beta01-05 15 10507 15.so.15.7[.0]
+ * 1.5.7rc01-03 15 10507 15.so.15.7[.0]
+ * 1.5.7 15 10507 15.so.15.7[.0]
+ * 1.6.0beta01-40 16 10600 16.so.16.0[.0]
+ * 1.6.0rc01-08 16 10600 16.so.16.0[.0]
+ * 1.6.0 16 10600 16.so.16.0[.0]
+ * 1.6.1beta01-09 16 10601 16.so.16.1[.0]
+ * 1.6.1rc01 16 10601 16.so.16.1[.0]
+ * 1.6.1 16 10601 16.so.16.1[.0]
+ * 1.6.2beta01 16 10602 16.so.16.2[.0]
+ * 1.6.2rc01-06 16 10602 16.so.16.2[.0]
+ * 1.6.2 16 10602 16.so.16.2[.0]
*
- * Henceforth the source version will match the shared-library major and
- * minor numbers; the shared-library major version number will be used for
- * changes in backward compatibility, as it is intended.
- * The PNG_LIBPNG_VER macro, which is not used within libpng but is
- * available for applications, is an unsigned integer of the form XYYZZ
- * corresponding to the source version X.Y.Z (leading zeros in Y and Z).
- * Beta versions were given the previous public release number plus a
- * letter, until version 1.0.6j; from then on they were given the upcoming
- * public release number plus "betaNN" or "rcNN".
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcNN".
*
- * Binary incompatibility exists only when applications make direct access
- * to the info_ptr or png_ptr members through png.h, and the compiled
- * application is loaded with a different version of the library.
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
*
- * See libpng.txt or libpng.3 for more information. The PNG specification
- * is available as a W3C Recommendation and as an ISO/IEC Standard; see
- *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng-manual.txt or libpng.3 for more information. The PNG
+ * specification is available as a W3C Recommendation and as an ISO
+ * Specification,
+ * at the actual function definitions and structure components.
*
* If you just need to read a PNG file and don't want to read the documentation
* skip to the end of this file and read the section entitled 'simplified API'.
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.55"
-#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
+#define PNG_LIBPNG_VER_STRING "1.6.2"
+#define PNG_HEADER_VERSION_STRING \
+ " libpng version 1.6.2 - April 25, 2013\n"
-/* The versions of shared library builds should stay in sync, going forward */
-#define PNG_LIBPNG_VER_SHAREDLIB 16
-#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
-#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
+#define PNG_LIBPNG_VER_SONUM 16
+#define PNG_LIBPNG_VER_DLLNUM 16
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 55
+#define PNG_LIBPNG_VER_RELEASE 2
-/* This should be zero for a public release, or non-zero for a
- * development version.
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
*/
-#define PNG_LIBPNG_VER_BUILD 0
+
+#define PNG_LIBPNG_VER_BUILD 0
/* Release Status */
-#define PNG_LIBPNG_BUILD_ALPHA 1
-#define PNG_LIBPNG_BUILD_BETA 2
-#define PNG_LIBPNG_BUILD_RC 3
-#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
/* Release-Specific Flags */
@@ -309,27 +419,26 @@
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
-/* Careful here. At one time, Guy wanted to use 082, but that
- * would be octal. We must not include leading zeros.
- * Versions 0.7 through 1.0.0 were in the range 0 to 100 here
- * (only version 1.0.0 was mis-numbered 100 instead of 10000).
- * From version 1.0.1 it is:
- * XXYYZZ, where XX=major, YY=minor, ZZ=release
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/
-#define PNG_LIBPNG_VER 10655 /* 1.6.55 */
+#define PNG_LIBPNG_VER 10602 /* 1.6.2 */
/* Library configuration: these options cannot be changed after
* the library has been built.
*/
#ifndef PNGLCONF_H
-/* If pnglibconf.h is missing, you can
- * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
- */
+ /* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
# include "pnglibconf.h"
#endif
#ifndef PNG_VERSION_INFO_ONLY
-/* Machine specific configuration. */
+ /* Machine specific configuration. */
# include "pngconf.h"
#endif
@@ -373,22 +482,17 @@ extern "C" {
/* This file is arranged in several sections:
*
- * 1. [omitted]
- * 2. Any configuration options that can be specified by for the application
+ * 1. Any configuration options that can be specified by for the application
* code when it is built. (Build time configuration is in pnglibconf.h)
- * 3. Type definitions (base types are defined in pngconf.h), structure
+ * 2. Type definitions (base types are defined in pngconf.h), structure
* definitions.
- * 4. Exported library functions.
- * 5. Simplified API.
- * 6. Implementation options.
+ * 3. Exported library functions.
+ * 4. Simplified API.
*
* The library source code has additional files (principally pngpriv.h) that
* allow configuration of the library.
*/
-
-/* Section 1: [omitted] */
-
-/* Section 2: run time configuration
+/* Section 1: run time configuration
* See pnglibconf.h for build time configuration
*
* Run time configuration allows the application to choose between
@@ -418,7 +522,7 @@ extern "C" {
* Otherwise the calls are mapped to png_error.
*/
-/* Section 3: type definitions, including structures and compile time
+/* Section 2: type definitions, including structures and compile time
* constants.
* See pngconf.h for base types that vary by machine/system
*/
@@ -426,7 +530,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char *png_libpng_version_1_6_55;
+typedef char* png_libpng_version_1_6_2;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@@ -567,8 +671,8 @@ typedef struct png_text_struct
png_charp key; /* keyword, 1-79 character description of "text" */
png_charp text; /* comment, may be an empty string (ie "")
or a NULL pointer */
- size_t text_length; /* length of the text string */
- size_t itxt_length; /* length of the itxt string */
+ png_size_t text_length; /* length of the text string */
+ png_size_t itxt_length; /* length of the itxt string */
png_charp lang; /* language code, 0-79 characters
or a NULL pointer */
png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
@@ -608,8 +712,7 @@ typedef png_time * png_timep;
typedef const png_time * png_const_timep;
typedef png_time * * png_timepp;
-#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\
- defined(PNG_USER_CHUNKS_SUPPORTED)
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
/* png_unknown_chunk is a structure to hold queued chunks for which there is
* no specific support. The idea is that we can use this to queue
* up private chunks for output even though the library doesn't actually
@@ -619,17 +722,17 @@ typedef png_time * * png_timepp;
*/
typedef struct png_unknown_chunk_t
{
- png_byte name[5]; /* Textual chunk name with '\0' terminator */
- png_byte *data; /* Data, should not be modified on read! */
- size_t size;
+ png_byte name[5]; /* Textual chunk name with '\0' terminator */
+ png_byte *data; /* Data, should not be modified on read! */
+ png_size_t size;
- /* On write 'location' must be set using the flag values listed below.
- * Notice that on read it is set by libpng however the values stored have
- * more bits set than are listed below. Always treat the value as a
- * bitmask. On write set only one bit - setting multiple bits may cause the
- * chunk to be written in multiple places.
- */
- png_byte location; /* mode of operation at read time */
+ /* On write 'location' must be set using the flag values listed below.
+ * Notice that on read it is set by libpng however the values stored have
+ * more bits set than are listed below. Always treat the value as a
+ * bitmask. On write set only one bit - setting multiple bits may cause the
+ * chunk to be written in multiple places.
+ */
+ png_byte location; /* mode of operation at read time */
}
png_unknown_chunk;
@@ -646,7 +749,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
/* Maximum positive integer used in PNG is (2^31)-1 */
#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
#define PNG_UINT_32_MAX ((png_uint_32)(-1))
-#define PNG_SIZE_MAX ((size_t)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
/* These are constants for fixed point values encoded in the
* PNG specification manner (x100000)
@@ -727,38 +830,22 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
* data in the info_struct to be written into the output file. The values
* of the PNG_INFO_ defines should NOT be changed.
*/
-#define PNG_INFO_gAMA 0x0001U
-#define PNG_INFO_sBIT 0x0002U
-#define PNG_INFO_cHRM 0x0004U
-#define PNG_INFO_PLTE 0x0008U
-#define PNG_INFO_tRNS 0x0010U
-#define PNG_INFO_bKGD 0x0020U
-#define PNG_INFO_hIST 0x0040U
-#define PNG_INFO_pHYs 0x0080U
-#define PNG_INFO_oFFs 0x0100U
-#define PNG_INFO_tIME 0x0200U
-#define PNG_INFO_pCAL 0x0400U
-#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */
-#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */
-#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */
-#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */
-#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */
-#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
-#define PNG_INFO_cICP 0x20000U /* PNGv3: 1.6.45 */
-#define PNG_INFO_cLLI 0x40000U /* PNGv3: 1.6.45 */
-#define PNG_INFO_mDCV 0x80000U /* PNGv3: 1.6.45 */
-/* APNG: these chunks are stored as unknown, these flags are never set
- * however they are provided as a convenience for implementors of APNG and
- * avoids any merge conflicts.
- *
- * Private chunks: these chunk names violate the chunk name recommendations
- * because the chunk definitions have no signature and because the private
- * chunks with these names have been reserved. Private definitions should
- * avoid them.
- */
-#define PNG_INFO_acTL 0x100000U /* PNGv3: 1.6.45: unknown */
-#define PNG_INFO_fcTL 0x200000U /* PNGv3: 1.6.45: unknown */
-#define PNG_INFO_fdAT 0x400000U /* PNGv3: 1.6.45: unknown */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */
/* This is used for the transformation routines, as some of them
* change these values for the row. It also should enable using
@@ -767,7 +854,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
typedef struct png_row_info_struct
{
png_uint_32 width; /* width of row */
- size_t rowbytes; /* number of bytes in row */
+ png_size_t rowbytes; /* number of bytes in row */
png_byte color_type; /* color type of row */
png_byte bit_depth; /* bit depth of row */
png_byte channels; /* number of channels (1, 2, 3, or 4) */
@@ -785,22 +872,17 @@ typedef png_row_info * * png_row_infopp;
* modify the buffer it is passed. The 'read' function, on the other hand, is
* expected to return the read data in the buffer.
*/
-typedef PNG_CALLBACK(void, *png_error_ptr,
- (png_structp, png_const_charp));
-typedef PNG_CALLBACK(void, *png_rw_ptr,
- (png_structp, png_bytep, size_t));
-typedef PNG_CALLBACK(void, *png_flush_ptr,
- (png_structp));
-typedef PNG_CALLBACK(void, *png_read_status_ptr,
- (png_structp, png_uint_32, int));
-typedef PNG_CALLBACK(void, *png_write_status_ptr,
- (png_structp, png_uint_32, int));
+typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
+typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
+typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
+typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
+ int));
+typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
+ int));
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-typedef PNG_CALLBACK(void, *png_progressive_info_ptr,
- (png_structp, png_infop));
-typedef PNG_CALLBACK(void, *png_progressive_end_ptr,
- (png_structp, png_infop));
+typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
/* The following callback receives png_uint_32 row_number, int pass for the
* png_bytep data of the row. When transforming an interlaced image the
@@ -812,19 +894,19 @@ typedef PNG_CALLBACK(void, *png_progressive_end_ptr,
* find the output pixel (x,y) given an interlaced sub-image pixel
* (row,col,pass). (See below for these macros.)
*/
-typedef PNG_CALLBACK(void, *png_progressive_row_ptr,
- (png_structp, png_bytep, png_uint_32, int));
+typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
+ png_uint_32, int));
#endif
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-typedef PNG_CALLBACK(void, *png_user_transform_ptr,
- (png_structp, png_row_infop, png_bytep));
+typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
+ png_bytep));
#endif
#ifdef PNG_USER_CHUNKS_SUPPORTED
-typedef PNG_CALLBACK(int, *png_user_chunk_ptr,
- (png_structp, png_unknown_chunkp));
+typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
+ png_unknown_chunkp));
#endif
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
/* not used anywhere */
@@ -843,7 +925,7 @@ typedef PNG_CALLBACK(int, *png_user_chunk_ptr,
* your compiler. This may be very difficult - try using a different compiler
* to build the library!
*/
-PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
+PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
#endif
/* Transform masks for the high-level interface */
@@ -867,9 +949,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
/* Added to libpng-1.5.4 */
#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */
-#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */
#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */
-#endif
/* Flags for MNG supported features */
#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
@@ -882,12 +962,11 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
* ignores the first argument) should be completely compatible with the
* following.
*/
-typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr,
- (png_structp, png_alloc_size_t));
-typedef PNG_CALLBACK(void, *png_free_ptr,
- (png_structp, png_voidp));
+typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
+ png_alloc_size_t));
+typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
-/* Section 4: exported functions
+/* Section 3: exported functions
* Here are the function definitions most commonly used. This is not
* the place to find out how to use libpng. See libpng-manual.txt for the
* full explanation, see example.c for the summary. This just provides
@@ -917,45 +996,43 @@ typedef PNG_CALLBACK(void, *png_free_ptr,
*/
/* Returns the version number of the library */
-PNG_EXPORT(1, png_uint_32, png_access_version_number,
- (void));
+PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
/* Tell lib we have already handled the first magic bytes.
* Handling more than 8 bytes from the beginning of the file is an error.
*/
-PNG_EXPORT(2, void, png_set_sig_bytes,
- (png_structrp png_ptr, int num_bytes));
+PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
* PNG file. Returns zero if the supplied bytes match the 8-byte PNG
* signature, and non-zero otherwise. Having num_to_check == 0 or
- * start > 7 will always fail (i.e. return non-zero).
+ * start > 7 will always fail (ie return non-zero).
*/
-PNG_EXPORT(3, int, png_sig_cmp,
- (png_const_bytep sig, size_t start, size_t num_to_check));
+PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
+ png_size_t num_to_check));
/* Simple signature checking function. This is the same as calling
- * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0).
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
*/
-#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */
+#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
/* Allocate and initialize png_ptr struct for reading, and any other memory. */
PNG_EXPORTA(4, png_structp, png_create_read_struct,
- (png_const_charp user_png_ver,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn),
- PNG_ALLOCATED);
+ (png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),
+ PNG_ALLOCATED);
/* Allocate and initialize png_ptr struct for writing, and any other memory */
PNG_EXPORTA(5, png_structp, png_create_write_struct,
- (png_const_charp user_png_ver,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn),
- PNG_ALLOCATED);
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn),
+ PNG_ALLOCATED);
-PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
- (png_const_structrp png_ptr));
+PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
+ (png_const_structrp png_ptr));
-PNG_EXPORT(7, void, png_set_compression_buffer_size,
- (png_structrp png_ptr, size_t size));
+PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+ png_size_t size));
/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
* match up.
@@ -968,8 +1045,8 @@ PNG_EXPORT(7, void, png_set_compression_buffer_size,
* allocated by the library - the call will return NULL on a mismatch
* indicating an ABI mismatch.
*/
-PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn,
- (png_structrp png_ptr, png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+ png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
# define png_jmpbuf(png_ptr) \
(*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
#else
@@ -981,77 +1058,67 @@ PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn,
* will use it; otherwise it will call PNG_ABORT(). This function was
* added in libpng-1.5.0.
*/
-PNG_EXPORTA(9, void, png_longjmp,
- (png_const_structrp png_ptr, int val),
- PNG_NORETURN);
+PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
+ PNG_NORETURN);
#ifdef PNG_READ_SUPPORTED
/* Reset the compression stream */
-PNG_EXPORTA(10, int, png_reset_zstream,
- (png_structrp png_ptr),
- PNG_DEPRECATED);
+PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
#endif
/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
#ifdef PNG_USER_MEM_SUPPORTED
PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
- (png_const_charp user_png_ver,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED);
+ PNG_ALLOCATED);
PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
- (png_const_charp user_png_ver,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED);
+ PNG_ALLOCATED);
#endif
/* Write the PNG file signature. */
-PNG_EXPORT(13, void, png_write_sig,
- (png_structrp png_ptr));
+PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
/* Write a PNG chunk - size, type, (optional) data, CRC. */
-PNG_EXPORT(14, void, png_write_chunk,
- (png_structrp png_ptr,
- png_const_bytep chunk_name, png_const_bytep data, size_t length));
+PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
+ chunk_name, png_const_bytep data, png_size_t length));
/* Write the start of a PNG chunk - length and chunk name. */
-PNG_EXPORT(15, void, png_write_chunk_start,
- (png_structrp png_ptr,
+PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
png_const_bytep chunk_name, png_uint_32 length));
/* Write the data of a PNG chunk started with png_write_chunk_start(). */
-PNG_EXPORT(16, void, png_write_chunk_data,
- (png_structrp png_ptr,
- png_const_bytep data, size_t length));
+PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
+ png_const_bytep data, png_size_t length));
/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
-PNG_EXPORT(17, void, png_write_chunk_end,
- (png_structrp png_ptr));
+PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
/* Allocate and initialize the info structure */
-PNG_EXPORTA(18, png_infop, png_create_info_struct,
- (png_const_structrp png_ptr),
- PNG_ALLOCATED);
+PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
+ PNG_ALLOCATED);
/* DEPRECATED: this function allowed init structures to be created using the
* default allocation method (typically malloc). Use is deprecated in 1.6.0 and
* the API will be removed in the future.
*/
-PNG_EXPORTA(19, void, png_info_init_3,
- (png_infopp info_ptr, size_t png_info_struct_size),
- PNG_DEPRECATED);
+PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
+ png_size_t png_info_struct_size), PNG_DEPRECATED);
/* Writes all the PNG information before the image. */
PNG_EXPORT(20, void, png_write_info_before_PLTE,
- (png_structrp png_ptr, png_const_inforp info_ptr));
+ (png_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(21, void, png_write_info,
- (png_structrp png_ptr, png_const_inforp info_ptr));
+ (png_structrp png_ptr, png_const_inforp info_ptr));
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read the information before the actual image data. */
PNG_EXPORT(22, void, png_read_info,
- (png_structrp png_ptr, png_inforp info_ptr));
+ (png_structrp png_ptr, png_inforp info_ptr));
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
@@ -1061,54 +1128,45 @@ PNG_EXPORT(22, void, png_read_info,
*/
#if PNG_LIBPNG_VER < 10700
/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
-PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123,
- (png_structrp png_ptr, png_const_timep ptime),
- PNG_DEPRECATED);
+PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
+ png_const_timep ptime),PNG_DEPRECATED);
#endif
-PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer,
- (char out[29], png_const_timep ptime));
+PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
+ png_const_timep ptime));
#endif
#ifdef PNG_CONVERT_tIME_SUPPORTED
/* Convert from a struct tm to png_time */
-PNG_EXPORT(24, void, png_convert_from_struct_tm,
- (png_timep ptime, const struct tm * ttime));
+PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
+ const struct tm * ttime));
/* Convert from time_t to png_time. Uses gmtime() */
-PNG_EXPORT(25, void, png_convert_from_time_t,
- (png_timep ptime, time_t ttime));
-#endif /* CONVERT_tIME */
+PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
+#endif /* PNG_CONVERT_tIME_SUPPORTED */
#ifdef PNG_READ_EXPAND_SUPPORTED
/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
-PNG_EXPORT(26, void, png_set_expand,
- (png_structrp png_ptr));
-PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8,
- (png_structrp png_ptr));
-PNG_EXPORT(28, void, png_set_palette_to_rgb,
- (png_structrp png_ptr));
-PNG_EXPORT(29, void, png_set_tRNS_to_alpha,
- (png_structrp png_ptr));
+PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
+PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
+PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
+PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED
/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
* of a tRNS chunk if present.
*/
-PNG_EXPORT(221, void, png_set_expand_16,
- (png_structrp png_ptr));
+PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* Use blue, green, red order for pixels. */
-PNG_EXPORT(30, void, png_set_bgr,
- (png_structrp png_ptr));
+PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
/* Expand the grayscale to 24-bit RGB if necessary. */
-PNG_EXPORT(31, void, png_set_gray_to_rgb,
- (png_structrp png_ptr));
+PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
@@ -1118,26 +1176,24 @@ PNG_EXPORT(31, void, png_set_gray_to_rgb,
#define PNG_ERROR_ACTION_ERROR 3
#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
-PNG_FP_EXPORT(32, void, png_set_rgb_to_gray,
- (png_structrp png_ptr,
+PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
int error_action, double red, double green))
-PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed,
- (png_structrp png_ptr,
+PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
int error_action, png_fixed_point red, png_fixed_point green))
-PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status,
- (png_const_structrp png_ptr));
+PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
+ png_ptr));
#endif
#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
-PNG_EXPORT(35, void, png_build_grayscale_palette,
- (int bit_depth, png_colorp palette));
+PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+ png_colorp palette));
#endif
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
-/* How the alpha channel is interpreted - this affects how the color channels
- * of a PNG file are returned to the calling application when an alpha channel,
- * or a tRNS chunk in a palette file, is present.
+/* How the alpha channel is interpreted - this affects how the color channels of
+ * a PNG file are returned when an alpha channel, or tRNS chunk in a palette
+ * file, is present.
*
* This has no effect on the way pixels are written into a PNG output
* datastream. The color samples in a PNG datastream are never premultiplied
@@ -1145,19 +1201,33 @@ PNG_EXPORT(35, void, png_build_grayscale_palette,
*
* The default is to return data according to the PNG specification: the alpha
* channel is a linear measure of the contribution of the pixel to the
- * corresponding composited pixel, and the color channels are unassociated
- * (not premultiplied). The gamma encoded color channels must be scaled
- * according to the contribution and to do this it is necessary to undo
- * the encoding, scale the color values, perform the composition and re-encode
+ * corresponding composited pixel. The gamma encoded color channels must be
+ * scaled according to the contribution and to do this it is necessary to undo
+ * the encoding, scale the color values, perform the composition and reencode
* the values. This is the 'PNG' mode.
*
* The alternative is to 'associate' the alpha with the color information by
- * storing color channel values that have been scaled by the alpha.
- * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
- * (the latter being the two common names for associated alpha color channels).
+ * storing color channel values that have been scaled by the alpha. The
+ * advantage is that the color channels can be resampled (the image can be
+ * scaled) in this form. The disadvantage is that normal practice is to store
+ * linear, not (gamma) encoded, values and this requires 16-bit channels for
+ * still images rather than the 8-bit channels that are just about sufficient if
+ * gamma encoding is used. In addition all non-transparent pixel values,
+ * including completely opaque ones, must be gamma encoded to produce the final
+ * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the
+ * latter being the two common names for associated alpha color channels.)
*
- * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha
- * value is equal to the maximum value.
+ * Since it is not necessary to perform arithmetic on opaque color values so
+ * long as they are not to be resampled and are in the final color space it is
+ * possible to optimize the handling of alpha by storing the opaque pixels in
+ * the PNG format (adjusted for the output color space) while storing partially
+ * opaque pixels in the standard, linear, format. The accuracy required for
+ * standard alpha composition is relatively low, because the pixels are
+ * isolated, therefore typically the accuracy loss in storing 8-bit linear
+ * values is acceptable. (This is not true if the alpha channel is used to
+ * simulate transparency over large areas - use 16 bits or the PNG mode in
+ * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is
+ * treated as opaque only if the alpha value is equal to the maximum value.
*
* The final choice is to gamma encode the alpha channel as well. This is
* broken because, in practice, no implementation that uses this choice
@@ -1176,15 +1246,76 @@ PNG_EXPORT(35, void, png_build_grayscale_palette,
#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */
#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */
-PNG_FP_EXPORT(227, void, png_set_alpha_mode,
- (png_structrp png_ptr, int mode, double output_gamma))
-PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed,
- (png_structrp png_ptr, int mode, png_fixed_point output_gamma))
+PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
+ double output_gamma))
+PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+ int mode, png_fixed_point output_gamma))
#endif
#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
/* The output_gamma value is a screen gamma in libpng terminology: it expresses
- * how to decode the output values, not how they are encoded.
+ * how to decode the output values, not how they are encoded. The values used
+ * correspond to the normal numbers used to describe the overall gamma of a
+ * computer display system; for example 2.2 for an sRGB conformant system. The
+ * values are scaled by 100000 in the _fixed version of the API (so 220000 for
+ * sRGB.)
+ *
+ * The inverse of the value is always used to provide a default for the PNG file
+ * encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+ * to override the PNG gamma information.
+ *
+ * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+ * opaque pixels however pixels with lower alpha values are not encoded,
+ * regardless of the output gamma setting.
+ *
+ * When the standard Porter Duff handling is requested with mode 1 the output
+ * encoding is set to be linear and the output_gamma value is only relevant
+ * as a default for input data that has no gamma information. The linear output
+ * encoding will be overridden if png_set_gamma() is called - the results may be
+ * highly unexpected!
+ *
+ * The following numbers are derived from the sRGB standard and the research
+ * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of
+ * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing
+ * correction required to take account of any differences in the color
+ * environment of the original scene and the intended display environment; the
+ * value expresses how to *decode* the image for display, not how the original
+ * data was *encoded*.
+ *
+ * sRGB provides a peg for the PNG standard by defining a viewing environment.
+ * sRGB itself, and earlier TV standards, actually use a more complex transform
+ * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is
+ * limited to simple power laws.) By saying that an image for direct display on
+ * an sRGB conformant system should be stored with a gAMA chunk value of 45455
+ * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+ * makes it possible to derive values for other display systems and
+ * environments.
+ *
+ * The Mac value is deduced from the sRGB based on an assumption that the actual
+ * extra viewing correction used in early Mac display systems was implemented as
+ * a power 1.45 lookup table.
+ *
+ * Any system where a programmable lookup table is used or where the behavior of
+ * the final display device characteristics can be changed requires system
+ * specific code to obtain the current characteristic. However this can be
+ * difficult and most PNG gamma correction only requires an approximate value.
+ *
+ * By default, if png_set_alpha_mode() is not called, libpng assumes that all
+ * values are unencoded, linear, values and that the output device also has a
+ * linear characteristic. This is only very rarely correct - it is invariably
+ * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+ * default if you don't know what the right answer is!
+ *
+ * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+ * 10.6) which used a correction table to implement a somewhat lower gamma on an
+ * otherwise sRGB system.
+ *
+ * Both these values are reserved (not simple gamma values) in order to allow
+ * more precise correction internally in the future.
+ *
+ * NOTE: the following values can be passed to either the fixed or floating
+ * point APIs, but the floating point API will also accept floating point
+ * values.
*/
#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */
#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */
@@ -1204,7 +1335,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed,
*
* png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
* In this case the output is assumed to be something like an sRGB conformant
- * display preceded by a power-law lookup table of power 1.45. This is how
+ * display preceeded by a power-law lookup table of power 1.45. This is how
* early Mac systems behaved.
*
* png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@@ -1251,7 +1382,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed,
*
* When the default gamma of PNG files doesn't match the output gamma.
* If you have PNG files with no gamma information png_set_alpha_mode allows
- * you to provide a default gamma, but it also sets the output gamma to the
+ * you to provide a default gamma, but it also sets the ouput gamma to the
* matching value. If you know your PNG files have a gamma that doesn't
* match the output you can take advantage of the fact that
* png_set_alpha_mode always sets the output gamma but only sets the PNG
@@ -1269,57 +1400,51 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed,
*/
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
-PNG_EXPORT(36, void, png_set_strip_alpha,
- (png_structrp png_ptr));
+PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
-PNG_EXPORT(37, void, png_set_swap_alpha,
- (png_structrp png_ptr));
+PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
-PNG_EXPORT(38, void, png_set_invert_alpha,
- (png_structrp png_ptr));
+PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
-/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
-PNG_EXPORT(39, void, png_set_filler,
- (png_structrp png_ptr, png_uint_32 filler, int flags));
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
+ int flags));
/* The values of the PNG_FILLER_ defines should NOT be changed */
# define PNG_FILLER_BEFORE 0
# define PNG_FILLER_AFTER 1
-/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
-PNG_EXPORT(40, void, png_set_add_alpha,
- (png_structrp png_ptr, png_uint_32 filler, int flags));
-#endif /* READ_FILLER || WRITE_FILLER */
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
+ png_uint_32 filler, int flags));
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Swap bytes in 16-bit depth files. */
-PNG_EXPORT(41, void, png_set_swap,
- (png_structrp png_ptr));
+PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
-PNG_EXPORT(42, void, png_set_packing,
- (png_structrp png_ptr));
+PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* Swap packing order of pixels in bytes. */
-PNG_EXPORT(43, void, png_set_packswap,
- (png_structrp png_ptr));
+PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
/* Converts files to legal bit depths. */
-PNG_EXPORT(44, void, png_set_shift,
- (png_structrp png_ptr, png_const_color_8p true_bits));
+PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+ true_bits));
#endif
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
@@ -1330,14 +1455,12 @@ PNG_EXPORT(44, void, png_set_shift,
* necessary to call png_read_row or png_read_rows png_get_image_height
* times for each pass.
*/
-PNG_EXPORT(45, int, png_set_interlace_handling,
- (png_structrp png_ptr));
+PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
/* Invert monochrome files */
-PNG_EXPORT(46, void, png_set_invert_mono,
- (png_structrp png_ptr));
+PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_BACKGROUND_SUPPORTED
@@ -1346,12 +1469,10 @@ PNG_EXPORT(46, void, png_set_invert_mono,
* read. Doing so will result in unexpected behavior and possible warnings or
* errors if the PNG file contains a bKGD chunk.
*/
-PNG_FP_EXPORT(47, void, png_set_background,
- (png_structrp png_ptr,
+PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
png_const_color_16p background_color, int background_gamma_code,
int need_expand, double background_gamma))
-PNG_FIXED_EXPORT(215, void, png_set_background_fixed,
- (png_structrp png_ptr,
+PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
png_const_color_16p background_color, int background_gamma_code,
int need_expand, png_fixed_point background_gamma))
#endif
@@ -1364,23 +1485,20 @@ PNG_FIXED_EXPORT(215, void, png_set_background_fixed,
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
/* Scale a 16-bit depth file down to 8-bit, accurately. */
-PNG_EXPORT(229, void, png_set_scale_16,
- (png_structrp png_ptr));
+PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
+#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
/* Strip the second byte of information from a 16-bit depth file. */
-PNG_EXPORT(48, void, png_set_strip_16,
- (png_structrp png_ptr));
+PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
/* Turn on quantizing, and reduce the palette to the number of colors
* available.
*/
-PNG_EXPORT(49, void, png_set_quantize,
- (png_structrp png_ptr,
+PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
png_colorp palette, int num_palette, int maximum_colors,
png_const_uint_16p histogram, int full_quantize));
#endif
@@ -1402,92 +1520,82 @@ PNG_EXPORT(49, void, png_set_quantize,
* API (floating point or fixed.) Notice, however, that the 'file_gamma' value
* is the inverse of a 'screen gamma' value.
*/
-PNG_FP_EXPORT(50, void, png_set_gamma,
- (png_structrp png_ptr,
+PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
double screen_gamma, double override_file_gamma))
-PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed,
- (png_structrp png_ptr,
+PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
#endif
#ifdef PNG_WRITE_FLUSH_SUPPORTED
/* Set how many lines between output flushes - 0 for no flushing */
-PNG_EXPORT(51, void, png_set_flush,
- (png_structrp png_ptr, int nrows));
+PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
/* Flush the current PNG output buffer */
-PNG_EXPORT(52, void, png_write_flush,
- (png_structrp png_ptr));
+PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
#endif
/* Optional update palette with requested transformations */
-PNG_EXPORT(53, void, png_start_read_image,
- (png_structrp png_ptr));
+PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
/* Optional call to update the users info structure */
-PNG_EXPORT(54, void, png_read_update_info,
- (png_structrp png_ptr, png_inforp info_ptr));
+PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
+ png_inforp info_ptr));
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read one or more rows of image data. */
-PNG_EXPORT(55, void, png_read_rows,
- (png_structrp png_ptr, png_bytepp row,
+PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
png_bytepp display_row, png_uint_32 num_rows));
#endif
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read a row of data. */
-PNG_EXPORT(56, void, png_read_row,
- (png_structrp png_ptr, png_bytep row, png_bytep display_row));
+PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
+ png_bytep display_row));
#endif
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read the whole image into memory at once. */
-PNG_EXPORT(57, void, png_read_image,
- (png_structrp png_ptr, png_bytepp image));
+PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
#endif
/* Write a row of image data */
-PNG_EXPORT(58, void, png_write_row,
- (png_structrp png_ptr, png_const_bytep row));
+PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
+ png_const_bytep row));
/* Write a few rows of image data: (*row) is not written; however, the type
* is declared as writeable to maintain compatibility with previous versions
* of libpng and to allow the 'display_row' array from read_rows to be passed
* unchanged to write_rows.
*/
-PNG_EXPORT(59, void, png_write_rows,
- (png_structrp png_ptr, png_bytepp row, png_uint_32 num_rows));
+PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
+ png_uint_32 num_rows));
/* Write the image data */
-PNG_EXPORT(60, void, png_write_image,
- (png_structrp png_ptr, png_bytepp image));
+PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
/* Write the end of the PNG file. */
-PNG_EXPORT(61, void, png_write_end,
- (png_structrp png_ptr, png_inforp info_ptr));
+PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
+ png_inforp info_ptr));
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read the end of the PNG file. */
-PNG_EXPORT(62, void, png_read_end,
- (png_structrp png_ptr, png_inforp info_ptr));
+PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
#endif
/* Free any memory associated with the png_info_struct */
-PNG_EXPORT(63, void, png_destroy_info_struct,
- (png_const_structrp png_ptr, png_infopp info_ptr_ptr));
+PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
+ png_infopp info_ptr_ptr));
/* Free any memory associated with the png_struct and the png_info_structs */
-PNG_EXPORT(64, void, png_destroy_read_struct,
- (png_structpp png_ptr_ptr,
+PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
/* Free any memory associated with the png_struct and the png_info_structs */
-PNG_EXPORT(65, void, png_destroy_write_struct,
- (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
+ png_infopp info_ptr_ptr));
/* Set the libpng method of handling chunk CRC errors */
-PNG_EXPORT(66, void, png_set_crc_action,
- (png_structrp png_ptr, int crit_action, int ancil_action));
+PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+ int ancil_action));
/* Values for png_set_crc_action() say how to handle CRC errors in
* ancillary and critical chunks, and whether to use the data contained
@@ -1505,21 +1613,19 @@ PNG_EXPORT(66, void, png_set_crc_action,
#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
-#ifdef PNG_WRITE_SUPPORTED
/* These functions give the user control over the scan-line filtering in
* libpng and the compression methods used by zlib. These functions are
* mainly useful for testing, as the defaults should work with most users.
* Those users who are tight on memory or want faster performance at the
* expense of compression can modify them. See the compression library
- * header file (zlib.h) for an explanation of the compression functions.
+ * header file (zlib.h) for an explination of the compression functions.
*/
/* Set the filtering method(s) used by libpng. Currently, the only valid
* value for "method" is 0.
*/
-PNG_EXPORT(67, void, png_set_filter,
- (png_structrp png_ptr, int method, int filters));
-#endif /* WRITE */
+PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+ int filters));
/* Flags for png_set_filter() to say which filters to use. The flags
* are chosen so that they don't conflict with real filter types
@@ -1532,8 +1638,8 @@ PNG_EXPORT(67, void, png_set_filter,
#define PNG_FILTER_UP 0x20
#define PNG_FILTER_AVG 0x40
#define PNG_FILTER_PAETH 0x80
-#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
-#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+ PNG_FILTER_AVG | PNG_FILTER_PAETH)
/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
* These defines should NOT be changed.
@@ -1545,74 +1651,99 @@ PNG_EXPORT(67, void, png_set_filter,
#define PNG_FILTER_VALUE_PAETH 4
#define PNG_FILTER_VALUE_LAST 5
-#ifdef PNG_WRITE_SUPPORTED
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
-PNG_FP_EXPORT(68, void, png_set_filter_heuristics,
- (png_structrp png_ptr,
- int heuristic_method, int num_weights,
- png_const_doublep filter_weights,
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows. Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters. This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified. Weights have no influence on
+ * the selection of the first row filter. Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type. Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs. There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs. Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found. If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
+ int heuristic_method, int num_weights, png_const_doublep filter_weights,
png_const_doublep filter_costs))
PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
- (png_structrp png_ptr,
- int heuristic_method, int num_weights,
+ (png_structrp png_ptr, int heuristic_method, int num_weights,
png_const_fixed_point_p filter_weights,
png_const_fixed_point_p filter_costs))
-#endif /* WRITE_WEIGHTED_FILTER */
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-/* The following are no longer used and will be removed from libpng-1.7: */
+/* Heuristic used for row filter selection. These defines should NOT be
+ * changed.
+ */
#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+#ifdef PNG_WRITE_SUPPORTED
/* Set the library compression level. Currently, valid values range from
* 0 - 9, corresponding directly to the zlib compression levels 0 - 9
* (0 - no compression, 9 - "maximal" compression). Note that tests have
* shown that zlib compression levels 3-6 usually perform as well as level 9
- * for PNG images, and do considerably fewer calculations. In the future,
+ * for PNG images, and do considerably fewer caclulations. In the future,
* these values may not correspond directly to the zlib compression levels.
*/
-#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
-PNG_EXPORT(69, void, png_set_compression_level,
- (png_structrp png_ptr, int level));
+PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
+ int level));
-PNG_EXPORT(70, void, png_set_compression_mem_level,
- (png_structrp png_ptr, int mem_level));
+PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
-PNG_EXPORT(71, void, png_set_compression_strategy,
- (png_structrp png_ptr, int strategy));
+PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
+ int strategy));
/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
* smaller value of window_bits if it can do so safely.
*/
-PNG_EXPORT(72, void, png_set_compression_window_bits,
- (png_structrp png_ptr, int window_bits));
+PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
+ int window_bits));
-PNG_EXPORT(73, void, png_set_compression_method,
- (png_structrp png_ptr, int method));
-#endif /* WRITE_CUSTOMIZE_COMPRESSION */
+PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
+ int method));
+#endif
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
/* Also set zlib parameters for compressing non-IDAT chunks */
-PNG_EXPORT(222, void, png_set_text_compression_level,
- (png_structrp png_ptr, int level));
+PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
+ int level));
-PNG_EXPORT(223, void, png_set_text_compression_mem_level,
- (png_structrp png_ptr, int mem_level));
+PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
-PNG_EXPORT(224, void, png_set_text_compression_strategy,
- (png_structrp png_ptr, int strategy));
+PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
+ int strategy));
/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
* smaller value of window_bits if it can do so safely.
*/
PNG_EXPORT(225, void, png_set_text_compression_window_bits,
- (png_structrp png_ptr, int window_bits));
+ (png_structrp png_ptr, int window_bits));
-PNG_EXPORT(226, void, png_set_text_compression_method,
- (png_structrp png_ptr, int method));
-#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
-#endif /* WRITE */
+PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+ int method));
+#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
/* These next functions are called for input/output, memory, and error
* handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
@@ -1625,8 +1756,7 @@ PNG_EXPORT(226, void, png_set_text_compression_method,
#ifdef PNG_STDIO_SUPPORTED
/* Initialize the input/output for the PNG file to the default functions. */
-PNG_EXPORT(74, void, png_init_io,
- (png_structrp png_ptr, FILE *fp));
+PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp));
#endif
/* Replace the (error and abort), and warning functions with user
@@ -1637,13 +1767,11 @@ PNG_EXPORT(74, void, png_init_io,
* default function will be used.
*/
-PNG_EXPORT(75, void, png_set_error_fn,
- (png_structrp png_ptr,
+PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
/* Return the user pointer associated with the error functions */
-PNG_EXPORT(76, png_voidp, png_get_error_ptr,
- (png_const_structrp png_ptr));
+PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
/* Replace the default data output functions with a user supplied one(s).
* If buffered output is not used, then output_flush_fn can be set to NULL.
@@ -1655,54 +1783,47 @@ PNG_EXPORT(76, png_voidp, png_get_error_ptr,
* default flush function, which uses the standard *FILE structure, will
* be used.
*/
-PNG_EXPORT(77, void, png_set_write_fn,
- (png_structrp png_ptr,
- png_voidp io_ptr,
+PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
/* Replace the default data input function with a user supplied one. */
-PNG_EXPORT(78, void, png_set_read_fn,
- (png_structrp png_ptr,
- png_voidp io_ptr, png_rw_ptr read_data_fn));
+PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn));
/* Return the user pointer associated with the I/O functions */
-PNG_EXPORT(79, png_voidp, png_get_io_ptr,
- (png_const_structrp png_ptr));
+PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
-PNG_EXPORT(80, void, png_set_read_status_fn,
- (png_structrp png_ptr, png_read_status_ptr read_row_fn));
+PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
+ png_read_status_ptr read_row_fn));
-PNG_EXPORT(81, void, png_set_write_status_fn,
- (png_structrp png_ptr, png_write_status_ptr write_row_fn));
+PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
+ png_write_status_ptr write_row_fn));
#ifdef PNG_USER_MEM_SUPPORTED
/* Replace the default memory allocation functions with user supplied one(s). */
-PNG_EXPORT(82, void, png_set_mem_fn,
- (png_structrp png_ptr,
- png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
/* Return the user pointer associated with the memory functions */
-PNG_EXPORT(83, png_voidp, png_get_mem_ptr,
- (png_const_structrp png_ptr));
+PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
#endif
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-PNG_EXPORT(84, void, png_set_read_user_transform_fn,
- (png_structrp png_ptr, png_user_transform_ptr read_user_transform_fn));
+PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr read_user_transform_fn));
#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
-PNG_EXPORT(85, void, png_set_write_user_transform_fn,
- (png_structrp png_ptr, png_user_transform_ptr write_user_transform_fn));
+PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr write_user_transform_fn));
#endif
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
-PNG_EXPORT(86, void, png_set_user_transform_info,
- (png_structrp png_ptr,
- png_voidp user_transform_ptr,
- int user_transform_depth, int user_transform_channels));
+PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
+ png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
/* Return the user pointer associated with the user transform functions */
PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
#endif
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
@@ -1717,10 +1838,8 @@ PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
* find the output pixel (x,y) given an interlaced sub-image pixel
* (row,col,pass). (See below for these macros.)
*/
-PNG_EXPORT(217, png_uint_32, png_get_current_row_number,
- (png_const_structrp));
-PNG_EXPORT(218, png_byte, png_get_current_pass_number,
- (png_const_structrp));
+PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
+PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
#endif
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
@@ -1735,41 +1854,37 @@ PNG_EXPORT(218, png_byte, png_get_current_pass_number,
*
* The integer return from the callback function is interpreted thus:
*
- * negative: An error occurred; png_chunk_error will be called.
+ * negative: An error occured, png_chunk_error will be called.
* zero: The chunk was not handled, the chunk will be saved. A critical
* chunk will cause an error at this point unless it is to be saved.
* positive: The chunk was handled, libpng will ignore/discard it.
*
- * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about
+ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about
* how this behavior will change in libpng 1.7
*/
-PNG_EXPORT(88, void, png_set_read_user_chunk_fn,
- (png_structrp png_ptr,
+PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
#endif
#ifdef PNG_USER_CHUNKS_SUPPORTED
-PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr,
- (png_const_structrp png_ptr));
+PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
#endif
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
/* Sets the function callbacks for the push reader, and a pointer to a
* user-defined structure available to the callback functions.
*/
-PNG_EXPORT(90, void, png_set_progressive_read_fn,
- (png_structrp png_ptr,
+PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
/* Returns the user pointer associated with the push read functions */
PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
/* Function to be called when data becomes available */
-PNG_EXPORT(92, void, png_process_data,
- (png_structrp png_ptr,
- png_inforp info_ptr, png_bytep buffer, size_t buffer_size));
+PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
+ png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));
/* A function which may be called *only* within png_process_data to stop the
* processing of any more data. The function returns the number of bytes
@@ -1778,8 +1893,7 @@ PNG_EXPORT(92, void, png_process_data,
* 'save' is set to true the routine will first save all the pending data and
* will always return 0.
*/
-PNG_EXPORT(219, size_t, png_process_data_pause,
- (png_structrp, int save));
+PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));
/* A function which may be called *only* outside (after) a call to
* png_process_data. It returns the number of bytes of data to skip in the
@@ -1787,127 +1901,112 @@ PNG_EXPORT(219, size_t, png_process_data_pause,
* application must skip than number of bytes of input data and pass the
* following data to the next call to png_process_data.
*/
-PNG_EXPORT(220, png_uint_32, png_process_data_skip,
- (png_structrp));
+PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
+#ifdef PNG_READ_INTERLACING_SUPPORTED
/* Function that combines rows. 'new_row' is a flag that should come from
* the callback and be non-NULL if anything needs to be done; the library
* stores its own version of the new data internally and ignores the passed
* in value.
*/
-PNG_EXPORT(93, void, png_progressive_combine_row,
- (png_const_structrp png_ptr,
+PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
png_bytep old_row, png_const_bytep new_row));
-#endif /* PROGRESSIVE_READ */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
-PNG_EXPORTA(94, png_voidp, png_malloc,
- (png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED);
+PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
/* Added at libpng version 1.4.0 */
-PNG_EXPORTA(95, png_voidp, png_calloc,
- (png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED);
+PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
/* Added at libpng version 1.2.4 */
-PNG_EXPORTA(96, png_voidp, png_malloc_warn,
- (png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED);
+PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
/* Frees a pointer allocated by png_malloc() */
-PNG_EXPORT(97, void, png_free,
- (png_const_structrp png_ptr, png_voidp ptr));
+PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
/* Free data that was allocated internally */
-PNG_EXPORT(98, void, png_free_data,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 free_me, int num));
+PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 free_me, int num));
-/* Reassign the responsibility for freeing existing data, whether allocated
+/* Reassign responsibility for freeing existing data, whether allocated
* by libpng or by the application; this works on the png_info structure passed
- * in, without changing the state for other png_info structures.
+ * in, it does not change the state for other png_info structures.
+ *
+ * It is unlikely that this function works correctly as of 1.6.0 and using it
+ * may result either in memory leaks or double free of allocated data.
*/
-PNG_EXPORT(99, void, png_data_freer,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- int freer, png_uint_32 mask));
+PNG_EXPORTA(99, void, png_data_freer, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED);
/* Assignments for png_data_freer */
#define PNG_DESTROY_WILL_FREE_DATA 1
-#define PNG_SET_WILL_FREE_DATA 1
-#define PNG_USER_WILL_FREE_DATA 2
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
/* Flags for png_ptr->free_me and info_ptr->free_me */
-#define PNG_FREE_HIST 0x0008U
-#define PNG_FREE_ICCP 0x0010U
-#define PNG_FREE_SPLT 0x0020U
-#define PNG_FREE_ROWS 0x0040U
-#define PNG_FREE_PCAL 0x0080U
-#define PNG_FREE_SCAL 0x0100U
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-# define PNG_FREE_UNKN 0x0200U
+# define PNG_FREE_UNKN 0x0200
#endif
-/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */
-#define PNG_FREE_PLTE 0x1000U
-#define PNG_FREE_TRNS 0x2000U
-#define PNG_FREE_TEXT 0x4000U
-#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
-#define PNG_FREE_ALL 0xffffU
-#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL 0x7fff
+#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
#ifdef PNG_USER_MEM_SUPPORTED
-PNG_EXPORTA(100, png_voidp, png_malloc_default,
- (png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED PNG_DEPRECATED);
-PNG_EXPORTA(101, void, png_free_default,
- (png_const_structrp png_ptr, png_voidp ptr),
- PNG_DEPRECATED);
+PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
+PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
+ png_voidp ptr), PNG_DEPRECATED);
#endif
#ifdef PNG_ERROR_TEXT_SUPPORTED
/* Fatal error in PNG image of libpng - can't continue */
-PNG_EXPORTA(102, void, png_error,
- (png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN);
+PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
/* The same, but the chunk name is prepended to the error string. */
-PNG_EXPORTA(103, void, png_chunk_error,
- (png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN);
+PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
#else
/* Fatal error in PNG image of libpng - can't continue */
-PNG_EXPORTA(104, void, png_err,
- (png_const_structrp png_ptr),
- PNG_NORETURN);
-# define png_error(s1,s2) png_err(s1)
-# define png_chunk_error(s1,s2) png_err(s1)
+PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
#endif
#ifdef PNG_WARNINGS_SUPPORTED
/* Non-fatal error in libpng. Can continue, but may have a problem. */
-PNG_EXPORT(105, void, png_warning,
- (png_const_structrp png_ptr, png_const_charp warning_message));
+PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
/* Non-fatal error in libpng, chunk name is prepended to message. */
-PNG_EXPORT(106, void, png_chunk_warning,
- (png_const_structrp png_ptr, png_const_charp warning_message));
-#else
-# define png_warning(s1,s2) ((void)(s1))
-# define png_chunk_warning(s1,s2) ((void)(s1))
+PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
#endif
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
/* Benign error in libpng. Can continue, but may have a problem.
* User can choose whether to handle as a fatal error or as a warning. */
-PNG_EXPORT(107, void, png_benign_error,
- (png_const_structrp png_ptr, png_const_charp warning_message));
+PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
#ifdef PNG_READ_SUPPORTED
/* Same, chunk name is prepended to message (only during read) */
-PNG_EXPORT(108, void, png_chunk_benign_error,
- (png_const_structrp png_ptr, png_const_charp warning_message));
+PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
#endif
PNG_EXPORT(109, void, png_set_benign_errors,
- (png_structrp png_ptr, int allowed));
+ (png_structrp png_ptr, int allowed));
#else
# ifdef PNG_ALLOW_BENIGN_ERRORS
# define png_benign_error png_warning
@@ -1931,413 +2030,274 @@ PNG_EXPORT(109, void, png_set_benign_errors,
* png_info_struct.
*/
/* Returns "flag" if chunk data is valid in info_ptr. */
-PNG_EXPORT(110, png_uint_32, png_get_valid,
- (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag));
+PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 flag));
/* Returns number of bytes needed to hold a transformed row. */
-PNG_EXPORT(111, size_t, png_get_rowbytes,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* Returns row_pointers, which is an array of pointers to scanlines that was
* returned from png_read_png().
*/
-PNG_EXPORT(112, png_bytepp, png_get_rows,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Set row_pointers, which is an array of pointers to scanlines for use
* by png_write_png().
*/
-PNG_EXPORT(113, void, png_set_rows,
- (png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers));
+PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytepp row_pointers));
#endif
/* Returns number of color channels in image. */
-PNG_EXPORT(114, png_byte, png_get_channels,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
#ifdef PNG_EASY_ACCESS_SUPPORTED
/* Returns image width in pixels. */
-PNG_EXPORT(115, png_uint_32, png_get_image_width,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image height in pixels. */
-PNG_EXPORT(116, png_uint_32, png_get_image_height,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image bit_depth. */
-PNG_EXPORT(117, png_byte, png_get_bit_depth,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image color_type. */
-PNG_EXPORT(118, png_byte, png_get_color_type,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image filter_type. */
-PNG_EXPORT(119, png_byte, png_get_filter_type,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image interlace_type. */
-PNG_EXPORT(120, png_byte, png_get_interlace_type,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image compression_type. */
-PNG_EXPORT(121, png_byte, png_get_compression_type,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
/* Returns image resolution in pixels per meter, from pHYs chunk data. */
PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
/* Returns pixel aspect ratio, computed from pHYs chunk data. */
PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
-#endif /* EASY_ACCESS */
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
#ifdef PNG_READ_SUPPORTED
/* Returns pointer to signature string read from PNG header */
-PNG_EXPORT(130, png_const_bytep, png_get_signature,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
#endif
#ifdef PNG_bKGD_SUPPORTED
-PNG_EXPORT(131, png_uint_32, png_get_bKGD,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_color_16p *background));
+PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_16p *background));
#endif
#ifdef PNG_bKGD_SUPPORTED
-PNG_EXPORT(132, void, png_set_bKGD,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_color_16p background));
+PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_16p background));
#endif
#ifdef PNG_cHRM_SUPPORTED
-PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *white_x, double *white_y,
- double *red_x, double *red_y,
- double *green_x, double *green_y,
- double *blue_x, double *blue_y))
-PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *red_X, double *red_Y, double *red_Z,
- double *green_X, double *green_Y, double *green_Z,
- double *blue_X, double *blue_Y, double *blue_Z))
+PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y))
+PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
+ double *green_X, double *green_Y, double *green_Z, double *blue_X,
+ double *blue_Y, double *blue_Z))
PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_white_x, png_fixed_point *int_white_y,
png_fixed_point *int_red_x, png_fixed_point *int_red_y,
png_fixed_point *int_green_x, png_fixed_point *int_green_y,
png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
- png_fixed_point *int_red_Z,
- png_fixed_point *int_green_X, png_fixed_point *int_green_Y,
- png_fixed_point *int_green_Z,
+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z))
#endif
#ifdef PNG_cHRM_SUPPORTED
-PNG_FP_EXPORT(135, void, png_set_cHRM,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- double white_x, double white_y,
- double red_x, double red_y,
- double green_x, double green_y,
- double blue_x, double blue_y))
-PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- double red_X, double red_Y, double red_Z,
- double green_X, double green_Y, double green_Z,
- double blue_X, double blue_Y, double blue_Z))
-PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y,
- png_fixed_point int_green_x, png_fixed_point int_green_y,
- png_fixed_point int_blue_x, png_fixed_point int_blue_y))
-PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_fixed_point int_red_X, png_fixed_point int_red_Y,
- png_fixed_point int_red_Z,
- png_fixed_point int_green_X, png_fixed_point int_green_Y,
- png_fixed_point int_green_Z,
+PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr,
+ double white_x, double white_y, double red_x, double red_y, double green_x,
+ double green_y, double blue_x, double blue_y))
+PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double red_X, double red_Y, double red_Z,
+ double green_X, double green_Y, double green_Z, double blue_X,
+ double blue_Y, double blue_Z))
+PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_white_x,
+ png_fixed_point int_white_y, png_fixed_point int_red_x,
+ png_fixed_point int_red_y, png_fixed_point int_green_x,
+ png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y))
+PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
+ png_fixed_point int_red_Z, png_fixed_point int_green_X,
+ png_fixed_point int_green_Y, png_fixed_point int_green_Z,
png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
png_fixed_point int_blue_Z))
#endif
-#ifdef PNG_cICP_SUPPORTED
-PNG_EXPORT(250, png_uint_32, png_get_cICP,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_bytep colour_primaries, png_bytep transfer_function,
- png_bytep matrix_coefficients, png_bytep video_full_range_flag));
-#endif
-
-#ifdef PNG_cICP_SUPPORTED
-PNG_EXPORT(251, void, png_set_cICP,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_byte colour_primaries, png_byte transfer_function,
- png_byte matrix_coefficients, png_byte video_full_range_flag));
-#endif
-
-#ifdef PNG_cLLI_SUPPORTED
-PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *maximum_content_light_level,
- double *maximum_frame_average_light_level))
-PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
- * 100,000 as in the case of png_fixed_point.
- */
- png_uint_32p maximum_content_light_level_scaled_by_10000,
- png_uint_32p maximum_frame_average_light_level_scaled_by_10000))
-#endif
-
-#ifdef PNG_cLLI_SUPPORTED
-PNG_FP_EXPORT(254, void, png_set_cLLI,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- double maximum_content_light_level,
- double maximum_frame_average_light_level))
-PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
- * 100,000 as in the case of png_fixed_point.
- */
- png_uint_32 maximum_content_light_level_scaled_by_10000,
- png_uint_32 maximum_frame_average_light_level_scaled_by_10000))
-#endif
-
-#ifdef PNG_eXIf_SUPPORTED
-PNG_EXPORT(246, png_uint_32, png_get_eXIf,
- (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *exif));
-PNG_EXPORT(247, void, png_set_eXIf,
- (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep exif));
-
-PNG_EXPORT(248, png_uint_32, png_get_eXIf_1,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32 *num_exif, png_bytep *exif));
-PNG_EXPORT(249, void, png_set_eXIf_1,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 num_exif, png_bytep exif));
-#endif
-
#ifdef PNG_gAMA_SUPPORTED
-PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *file_gamma))
+PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *file_gamma))
PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_file_gamma))
#endif
#ifdef PNG_gAMA_SUPPORTED
-PNG_FP_EXPORT(139, void, png_set_gAMA,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- double file_gamma))
-PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_fixed_point int_file_gamma))
+PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double file_gamma))
+PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_file_gamma))
#endif
#ifdef PNG_hIST_SUPPORTED
-PNG_EXPORT(141, png_uint_32, png_get_hIST,
- (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_16p *hist));
-PNG_EXPORT(142, void, png_set_hIST,
- (png_const_structrp png_ptr, png_inforp info_ptr, png_const_uint_16p hist));
+PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_16p *hist));
#endif
-PNG_EXPORT(143, png_uint_32, png_get_IHDR,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32 *width, png_uint_32 *height,
- int *bit_depth, int *color_type,
- int *interlace_method, int *compression_method, int *filter_method));
-
-PNG_EXPORT(144, void, png_set_IHDR,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 width, png_uint_32 height,
- int bit_depth, int color_type,
- int interlace_method, int compression_method, int filter_method));
-
-#ifdef PNG_mDCV_SUPPORTED
-PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- /* The chromaticities of the mastering display. As cHRM, but independent of
- * the encoding endpoints in cHRM, or cICP, or iCCP. These values will
- * always be in the range 0 to 1.3107.
- */
- double *white_x, double *white_y,
- double *red_x, double *red_y,
- double *green_x, double *green_y,
- double *blue_x, double *blue_y,
- /* Mastering display luminance in cd/m2 (nits). */
- double *mastering_display_maximum_luminance,
- double *mastering_display_minimum_luminance))
-
-PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_fixed_point *int_white_x, png_fixed_point *int_white_y,
- png_fixed_point *int_red_x, png_fixed_point *int_red_y,
- png_fixed_point *int_green_x, png_fixed_point *int_green_y,
- png_fixed_point *int_blue_x, png_fixed_point *int_blue_y,
- /* Mastering display luminance in cd/m2 (nits) multiplied (scaled) by
- * 10,000.
- */
- png_uint_32p mastering_display_maximum_luminance_scaled_by_10000,
- png_uint_32p mastering_display_minimum_luminance_scaled_by_10000))
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_uint_16p hist));
#endif
-#ifdef PNG_mDCV_SUPPORTED
-PNG_FP_EXPORT(258, void, png_set_mDCV,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- /* The chromaticities of the mastering display. As cHRM, but independent of
- * the encoding endpoints in cHRM, or cICP, or iCCP.
- */
- double white_x, double white_y,
- double red_x, double red_y,
- double green_x, double green_y,
- double blue_x, double blue_y,
- /* Mastering display luminance in cd/m2 (nits). */
- double mastering_display_maximum_luminance,
- double mastering_display_minimum_luminance))
+PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
-PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- /* The admissible range of these values is not the full range of a PNG
- * fixed point value. Negative values cannot be encoded and the maximum
- * value is about 1.3 */
- png_fixed_point int_white_x, png_fixed_point int_white_y,
- png_fixed_point int_red_x, png_fixed_point int_red_y,
- png_fixed_point int_green_x, png_fixed_point int_green_y,
- png_fixed_point int_blue_x, png_fixed_point int_blue_y,
- /* These are PNG unsigned 4 byte values: 31-bit unsigned values. The MSB
- * must be zero.
- */
- png_uint_32 mastering_display_maximum_luminance_scaled_by_10000,
- png_uint_32 mastering_display_minimum_luminance_scaled_by_10000))
+PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
#endif
#ifdef PNG_oFFs_SUPPORTED
-PNG_EXPORT(145, png_uint_32, png_get_oFFs,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type));
-#endif
-
-#ifdef PNG_oFFs_SUPPORTED
-PNG_EXPORT(146, void, png_set_oFFs,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_int_32 offset_x, png_int_32 offset_y, int unit_type));
+PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
#endif
#ifdef PNG_pCAL_SUPPORTED
-PNG_EXPORT(147, png_uint_32, png_get_pCAL,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
- int *type, int *nparams, png_charp *units, png_charpp *params));
+PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
+ png_int_32 *X1, int *type, int *nparams, png_charp *units,
+ png_charpp *params));
#endif
#ifdef PNG_pCAL_SUPPORTED
-PNG_EXPORT(148, void, png_set_pCAL,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_charp purpose, png_int_32 X0, png_int_32 X1,
+PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
int type, int nparams, png_const_charp units, png_charpp params));
#endif
#ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(149, png_uint_32, png_get_pHYs,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
#endif
#ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(150, void, png_set_pHYs,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
#endif
-PNG_EXPORT(151, png_uint_32, png_get_PLTE,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_colorp *palette, int *num_palette));
+PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_colorp *palette, int *num_palette));
-PNG_EXPORT(152, void, png_set_PLTE,
- (png_structrp png_ptr, png_inforp info_ptr,
- png_const_colorp palette, int num_palette));
+PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_colorp palette, int num_palette));
#ifdef PNG_sBIT_SUPPORTED
-PNG_EXPORT(153, png_uint_32, png_get_sBIT,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_color_8p *sig_bit));
+PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_8p *sig_bit));
#endif
#ifdef PNG_sBIT_SUPPORTED
-PNG_EXPORT(154, void, png_set_sBIT,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_color_8p sig_bit));
+PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_8p sig_bit));
#endif
#ifdef PNG_sRGB_SUPPORTED
-PNG_EXPORT(155, png_uint_32, png_get_sRGB,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- int *file_srgb_intent));
+PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *file_srgb_intent));
#endif
#ifdef PNG_sRGB_SUPPORTED
-PNG_EXPORT(156, void, png_set_sRGB,
- (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent));
-PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM,
- (png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent));
+PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
+PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
#endif
#ifdef PNG_iCCP_SUPPORTED
-PNG_EXPORT(158, png_uint_32, png_get_iCCP,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_charpp name, int *compression_type,
+PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charpp name, int *compression_type,
png_bytepp profile, png_uint_32 *proflen));
#endif
#ifdef PNG_iCCP_SUPPORTED
-PNG_EXPORT(159, void, png_set_iCCP,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_charp name, int compression_type,
+PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp name, int compression_type,
png_const_bytep profile, png_uint_32 proflen));
#endif
#ifdef PNG_sPLT_SUPPORTED
-PNG_EXPORT(160, int, png_get_sPLT,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_sPLT_tpp entries));
+PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_sPLT_tpp entries));
#endif
#ifdef PNG_sPLT_SUPPORTED
-PNG_EXPORT(161, void, png_set_sPLT,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_sPLT_tp entries, int nentries));
+PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
#endif
#ifdef PNG_TEXT_SUPPORTED
/* png_get_text also returns the number of text chunks in *num_text */
-PNG_EXPORT(162, int, png_get_text,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_textp *text_ptr, int *num_text));
+PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_textp *text_ptr, int *num_text));
#endif
/* Note while png_set_text() will accept a structure whose text,
@@ -2348,41 +2308,35 @@ PNG_EXPORT(162, int, png_get_text,
*/
#ifdef PNG_TEXT_SUPPORTED
-PNG_EXPORT(163, void, png_set_text,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_textp text_ptr, int num_text));
+PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text));
#endif
#ifdef PNG_tIME_SUPPORTED
-PNG_EXPORT(164, png_uint_32, png_get_tIME,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_timep *mod_time));
+PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_timep *mod_time));
#endif
#ifdef PNG_tIME_SUPPORTED
-PNG_EXPORT(165, void, png_set_tIME,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_timep mod_time));
+PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_timep mod_time));
#endif
#ifdef PNG_tRNS_SUPPORTED
-PNG_EXPORT(166, png_uint_32, png_get_tRNS,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_bytep *trans_alpha, int *num_trans,
+PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
png_color_16p *trans_color));
#endif
#ifdef PNG_tRNS_SUPPORTED
-PNG_EXPORT(167, void, png_set_tRNS,
- (png_structrp png_ptr, png_inforp info_ptr,
- png_const_bytep trans_alpha, int num_trans,
+PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
png_const_color_16p trans_color));
#endif
#ifdef PNG_sCAL_SUPPORTED
-PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- int *unit, double *width, double *height))
+PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *unit, double *width, double *height))
#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
defined(PNG_FLOATING_POINT_SUPPORTED)
/* NOTE: this API is currently implemented using floating point arithmetic,
@@ -2391,23 +2345,22 @@ PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL,
* is highly recommended that png_get_sCAL_s be used instead.
*/
PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- int *unit, png_fixed_point *width, png_fixed_point *height))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_fixed_point *width, png_fixed_point *height))
#endif
PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- int *unit, png_charpp swidth, png_charpp sheight));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_charpp swidth, png_charpp sheight));
-PNG_FP_EXPORT(170, void, png_set_sCAL,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- int unit, double width, double height))
-PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- int unit, png_fixed_point width, png_fixed_point height))
-PNG_EXPORT(171, void, png_set_sCAL_s,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- int unit, png_const_charp swidth, png_const_charp sheight));
-#endif /* sCAL */
+PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, double width, double height))
+PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, png_fixed_point width,
+ png_fixed_point height))
+PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit,
+ png_const_charp swidth, png_const_charp sheight));
+#endif /* PNG_sCAL_SUPPORTED */
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
/* Provide the default handling for all unknown chunks or, optionally, for
@@ -2441,7 +2394,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s,
* to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
* it simply resets the behavior to the libpng default.
*
- * INTERACTION WITH USER CHUNK CALLBACKS:
+ * INTERACTION WTIH USER CHUNK CALLBACKS:
* The per-chunk handling is always used when there is a png_user_chunk_ptr
* callback and the callback returns 0; the chunk is then always stored *unless*
* it is critical and the per-chunk setting is other than ALWAYS. Notice that
@@ -2508,24 +2461,21 @@ PNG_EXPORT(171, void, png_set_sCAL_s,
* except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
* be processed by libpng.
*/
-#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
-PNG_EXPORT(172, void, png_set_keep_unknown_chunks,
- (png_structrp png_ptr,
+PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
int keep, png_const_bytep chunk_list, int num_chunks));
-#endif /* HANDLE_AS_UNKNOWN */
/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
* the result is therefore true (non-zero) if special handling is required,
* false for the default handling.
*/
-PNG_EXPORT(173, int, png_handle_as_unknown,
- (png_const_structrp png_ptr, png_const_bytep chunk_name));
-#endif /* SET_UNKNOWN_CHUNKS */
+PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
+ png_const_bytep chunk_name));
+#endif
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-PNG_EXPORT(174, void, png_set_unknown_chunks,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_const_unknown_chunkp unknowns, int num_unknowns));
+PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns,
+ int num_unknowns));
/* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
* unknowns to the location currently stored in the png_struct. This is
* invariably the wrong value on write. To fix this call the following API
@@ -2536,47 +2486,39 @@ PNG_EXPORT(174, void, png_set_unknown_chunks,
*/
PNG_EXPORT(175, void, png_set_unknown_chunk_location,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- int chunk, int location));
+ (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
-PNG_EXPORT(176, int, png_get_unknown_chunks,
- (png_const_structrp png_ptr, png_inforp info_ptr,
- png_unknown_chunkpp entries));
+PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_unknown_chunkpp entries));
#endif
/* Png_free_data() will turn off the "valid" flag for anything it frees.
* If you need to turn it off for a chunk that your application has freed,
* you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
*/
-PNG_EXPORT(177, void, png_set_invalid,
- (png_const_structrp png_ptr, png_inforp info_ptr, int mask));
+PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int mask));
#ifdef PNG_INFO_IMAGE_SUPPORTED
/* The "params" pointer is currently not used and is for future expansion. */
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-PNG_EXPORT(178, void, png_read_png,
- (png_structrp png_ptr, png_inforp info_ptr,
+PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
int transforms, png_voidp params));
-#endif
-#ifdef PNG_WRITE_SUPPORTED
-PNG_EXPORT(179, void, png_write_png,
- (png_structrp png_ptr, png_inforp info_ptr,
+PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
int transforms, png_voidp params));
#endif
-#endif
PNG_EXPORT(180, png_const_charp, png_get_copyright,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
PNG_EXPORT(181, png_const_charp, png_get_header_ver,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
PNG_EXPORT(182, png_const_charp, png_get_header_version,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
#ifdef PNG_MNG_FEATURES_SUPPORTED
-PNG_EXPORT(184, png_uint_32, png_permit_mng_features,
- (png_structrp png_ptr, png_uint_32 mng_features_permitted));
+PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+ png_uint_32 mng_features_permitted));
#endif
/* For use in png_set_keep_unknown, added to version 1.2.6 */
@@ -2590,74 +2532,71 @@ PNG_EXPORT(184, png_uint_32, png_permit_mng_features,
* messages before passing them to the error or warning handler.
*/
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
-PNG_EXPORT(185, void, png_set_strip_error_numbers,
- (png_structrp png_ptr, png_uint_32 strip_mode));
+PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
+ png_uint_32 strip_mode));
#endif
/* Added in libpng-1.2.6 */
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
-PNG_EXPORT(186, void, png_set_user_limits,
- (png_structrp png_ptr,
+PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
png_uint_32 user_width_max, png_uint_32 user_height_max));
PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
/* Added in libpng-1.4.0 */
-PNG_EXPORT(189, void, png_set_chunk_cache_max,
- (png_structrp png_ptr, png_uint_32 user_chunk_cache_max));
+PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
+ png_uint_32 user_chunk_cache_max));
PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
/* Added in libpng-1.4.1 */
-PNG_EXPORT(191, void, png_set_chunk_malloc_max,
- (png_structrp png_ptr, png_alloc_size_t user_chunk_cache_max));
+PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
+ png_alloc_size_t user_chunk_cache_max));
PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
#endif
#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
- (png_const_structrp png_ptr, png_const_inforp info_ptr));
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
#endif
-PNG_FP_EXPORT(197, float, png_get_y_offset_inches,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr))
#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
- (png_const_structrp png_ptr, png_const_inforp info_ptr))
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
#endif
# ifdef PNG_pHYs_SUPPORTED
-PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi,
- (png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-# endif /* pHYs */
-#endif /* INCH_CONVERSIONS */
+PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
+# endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */
/* Added in libpng-1.4.0 */
#ifdef PNG_IO_STATE_SUPPORTED
-PNG_EXPORT(199, png_uint_32, png_get_io_state,
- (png_const_structrp png_ptr));
+PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
/* Removed from libpng 1.6; use png_get_io_chunk_type. */
-PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name,
- (png_structrp png_ptr),
- PNG_DEPRECATED)
+PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
+ PNG_DEPRECATED)
PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
- (png_const_structrp png_ptr));
+ (png_const_structrp png_ptr));
/* The flags returned by png_get_io_state() are the following: */
# define PNG_IO_NONE 0x0000 /* no I/O at this moment */
@@ -2669,7 +2608,7 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */
# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */
# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */
-#endif /* IO_STATE */
+#endif /* ?PNG_IO_STATE_SUPPORTED */
/* Interlace support. The following macros are always defined so that if
* libpng interlace handling is turned off the macros may be used to handle
@@ -2748,60 +2687,49 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
/* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
-# define png_composite(composite, fg, alpha, bg) \
- { \
- png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
- * (png_uint_16)(alpha) \
- + (png_uint_16)(bg)*(png_uint_16)(255 \
- - (png_uint_16)(alpha)) + 128); \
- (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
- }
+# define png_composite(composite, fg, alpha, bg) \
+ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+ * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 \
+ - (png_uint_16)(alpha)) + 128); \
+ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
-# define png_composite_16(composite, fg, alpha, bg) \
- { \
- png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
- * (png_uint_32)(alpha) \
- + (png_uint_32)(bg)*(65535 \
- - (png_uint_32)(alpha)) + 32768); \
- (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
- }
+# define png_composite_16(composite, fg, alpha, bg) \
+ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+ * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(65535 \
+ - (png_uint_32)(alpha)) + 32768); \
+ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
#else /* Standard method using integer division */
-# define png_composite(composite, fg, alpha, bg) \
- (composite) = \
- (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \
- (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
- 127) / 255))
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ 127) / 255)
-# define png_composite_16(composite, fg, alpha, bg) \
- (composite) = \
- (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
- (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
- 32767) / 65535))
-#endif /* READ_COMPOSITE_NODIV */
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
+ 32767) / 65535)
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(201, png_uint_32, png_get_uint_32,
- (png_const_bytep buf));
-PNG_EXPORT(202, png_uint_16, png_get_uint_16,
- (png_const_bytep buf));
-PNG_EXPORT(203, png_int_32, png_get_int_32,
- (png_const_bytep buf));
+PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
+PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
+PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
#endif
-PNG_EXPORT(204, png_uint_32, png_get_uint_31,
- (png_const_structrp png_ptr, png_const_bytep buf));
+PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
+ png_const_bytep buf));
/* No png_get_int_16 -- may be added if there's a real need for it. */
/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(205, void, png_save_uint_32,
- (png_bytep buf, png_uint_32 i));
+PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
#endif
#ifdef PNG_SAVE_INT_32_SUPPORTED
-PNG_EXPORT(206, void, png_save_int_32,
- (png_bytep buf, png_int_32 i));
+PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
#endif
/* Place a 16-bit number into a buffer in PNG byte order.
@@ -2809,8 +2737,7 @@ PNG_EXPORT(206, void, png_save_int_32,
* just to avoid potential problems on pre-ANSI C compilers.
*/
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
-PNG_EXPORT(207, void, png_save_uint_16,
- (png_bytep buf, unsigned int i));
+PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
/* No png_save_int_16 -- may be added if there's a real need for it. */
#endif
@@ -2820,52 +2747,43 @@ PNG_EXPORT(207, void, png_save_uint_16,
* format for negative values, which is almost certainly true.
*/
# define PNG_get_uint_32(buf) \
- (((png_uint_32)(*(buf)) << 24) + \
- ((png_uint_32)(*((buf) + 1)) << 16) + \
- ((png_uint_32)(*((buf) + 2)) << 8) + \
- ((png_uint_32)(*((buf) + 3))))
+ (((png_uint_32)(*(buf)) << 24) + \
+ ((png_uint_32)(*((buf) + 1)) << 16) + \
+ ((png_uint_32)(*((buf) + 2)) << 8) + \
+ ((png_uint_32)(*((buf) + 3))))
/* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
* function) incorrectly returned a value of type png_uint_32.
*/
# define PNG_get_uint_16(buf) \
- ((png_uint_16) \
- (((unsigned int)(*(buf)) << 8) + \
- ((unsigned int)(*((buf) + 1)))))
+ ((png_uint_16) \
+ (((unsigned int)(*(buf)) << 8) + \
+ ((unsigned int)(*((buf) + 1)))))
# define PNG_get_int_32(buf) \
- ((png_int_32)((*(buf) & 0x80) \
- ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
- : (png_int_32)png_get_uint_32(buf)))
+ ((png_int_32)((*(buf) & 0x80) \
+ ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \
+ : (png_int_32)png_get_uint_32(buf)))
-/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
- * but defining a macro name prefixed with PNG_PREFIX.
- */
+ /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
# ifndef PNG_PREFIX
-# define png_get_uint_32(buf) PNG_get_uint_32(buf)
-# define png_get_uint_16(buf) PNG_get_uint_16(buf)
-# define png_get_int_32(buf) PNG_get_int_32(buf)
+# define png_get_uint_32(buf) PNG_get_uint_32(buf)
+# define png_get_uint_16(buf) PNG_get_uint_16(buf)
+# define png_get_int_32(buf) PNG_get_int_32(buf)
# endif
#else
# ifdef PNG_PREFIX
- /* No macros; revert to the (redefined) function */
-# define PNG_get_uint_32 (png_get_uint_32)
-# define PNG_get_uint_16 (png_get_uint_16)
-# define PNG_get_int_32 (png_get_int_32)
+ /* No macros; revert to the (redefined) function */
+# define PNG_get_uint_32 (png_get_uint_32)
+# define PNG_get_uint_16 (png_get_uint_16)
+# define PNG_get_int_32 (png_get_int_32)
# endif
#endif
-#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
-PNG_EXPORT(242, void, png_set_check_for_invalid_index,
- (png_structrp png_ptr, int allowed));
-# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
-PNG_EXPORT(243, int, png_get_palette_max,
- (png_const_structp png_ptr, png_const_infop info_ptr));
-# endif
-#endif /* CHECK_FOR_INVALID_INDEX */
-
/*******************************************************************************
- * Section 5: SIMPLIFIED API
+ * SIMPLIFIED API
*******************************************************************************
*
* Please read the documentation in libpng-manual.txt (TODO: write said
@@ -2874,16 +2792,15 @@ PNG_EXPORT(243, int, png_get_palette_max,
* The simplified API hides the details of both libpng and the PNG file format
* itself. It allows PNG files to be read into a very limited number of
* in-memory bitmap formats or to be written from the same formats. If these
- * formats do not accommodate your needs then you can, and should, use the more
+ * formats do not accomodate your needs then you can, and should, use the more
* sophisticated APIs above - these support a wide variety of in-memory formats
* and a wide variety of sophisticated transformations to those formats as well
* as a wide variety of APIs to manipulate ancillary information.
*
* To read a PNG file using the simplified API:
*
- * 1) Declare a 'png_image' structure (see below) on the stack, set the
- * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
- * (this is REQUIRED, your program may crash if you don't do it.)
+ * 1) Declare a 'png_image' structure (see below) on the stack and set the
+ * version field to PNG_IMAGE_VERSION.
* 2) Call the appropriate png_image_begin_read... function.
* 3) Set the png_image 'format' member to the required sample format.
* 4) Allocate a buffer for the image and, if required, the color-map.
@@ -2910,9 +2827,6 @@ PNG_EXPORT(243, int, png_get_palette_max,
* when it is being read or defines the in-memory format of an image that you
* need to write:
*/
-#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
- defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
-
#define PNG_IMAGE_VERSION 1
typedef struct png_control *png_controlp;
@@ -2939,7 +2853,7 @@ typedef struct
# define PNG_IMAGE_WARNING 1
# define PNG_IMAGE_ERROR 2
/*
- * The result is a two-bit code such that a value more than 1 indicates
+ * The result is a two bit code such that a value more than 1 indicates
* a failure in the API just called:
*
* 0 - no warning or error
@@ -2980,7 +2894,7 @@ typedef struct
*
* When the simplified API needs to convert between sRGB and linear colorspaces,
* the actual sRGB transfer curve defined in the sRGB specification (see the
- * article at ) is used, not the gamma=1/2.2
+ * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
* approximation used elsewhere in libpng.
*
* When an alpha channel is present it is expected to denote pixel coverage
@@ -3012,7 +2926,7 @@ typedef struct
* called to read or write the color-map and set the format correctly for the
* image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
*
- * NOTE: libpng can be built with particular features disabled. If you see
+ * NOTE: libpng can be built with particular features disabled, if you see
* compiler errors because the definition of one of the following flags has been
* compiled out it is because libpng does not have the required support. It is
* possible, however, for the libpng configuration to enable the format on just
@@ -3024,7 +2938,7 @@ typedef struct
*/
#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */
#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */
-#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */
+#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */
#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
#ifdef PNG_FORMAT_BGR_SUPPORTED
@@ -3035,8 +2949,6 @@ typedef struct
# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
#endif
-#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
-
/* Commonly used formats have predefined macros.
*
* First the single byte (sRGB) formats:
@@ -3148,19 +3060,12 @@ typedef struct
* is the minimum 'row stride', the minimum count of components between each
* row. For a color-mapped image this is the minimum number of bytes in a
* row.
- *
- * WARNING: this macro overflows for some images with more than one component
- * and very large image widths. libpng will refuse to process an image where
- * this macro would overflow.
*/
#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
(PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
/* Return the size, in bytes, of an image buffer given a png_image and a row
* stride - the number of components to leave space for in each row.
- *
- * WARNING: this macro overflows a 32-bit integer for some large PNG images,
- * libpng will refuse to process an image where such an overflow would occur.
*/
#define PNG_IMAGE_SIZE(image)\
@@ -3183,7 +3088,7 @@ typedef struct
* 'flags' field of png_image.
*/
#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
- /* This indicates that the RGB values of the in-memory bitmap do not
+ /* This indicates the the RGB values of the in-memory bitmap do not
* correspond to the red, green and blue end-points defined by sRGB.
*/
@@ -3224,25 +3129,24 @@ typedef struct
* the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
*/
#ifdef PNG_STDIO_SUPPORTED
-PNG_EXPORT(234, int, png_image_begin_read_from_file,
- (png_imagep image, const char *file_name));
+PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
+ const char *file_name));
/* The named file is opened for read and the image header is filled in
* from the PNG header in the file.
*/
-PNG_EXPORT(235, int, png_image_begin_read_from_stdio,
- (png_imagep image, FILE *file));
+PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
+ FILE* file));
/* The PNG header is read from the stdio FILE object. */
-#endif /* STDIO */
+#endif /* PNG_STDIO_SUPPORTED */
-PNG_EXPORT(236, int, png_image_begin_read_from_memory,
- (png_imagep image, png_const_voidp memory, size_t size));
+PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
+ png_const_voidp memory, png_size_t size));
/* The PNG header is read from the given memory buffer. */
-PNG_EXPORT(237, int, png_image_finish_read,
- (png_imagep image,
- png_const_colorp background, void *buffer, png_int_32 row_stride,
- void *colormap));
+PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+ png_const_colorp background, void *buffer, png_int_32 row_stride,
+ void *colormap));
/* Finish reading the image into the supplied buffer and clean up the
* png_image structure.
*
@@ -3275,12 +3179,11 @@ PNG_EXPORT(237, int, png_image_finish_read,
* written to the colormap; this may be less than the original value.
*/
-PNG_EXPORT(238, void, png_image_free,
- (png_imagep image));
+PNG_EXPORT(238, void, png_image_free, (png_imagep image));
/* Free any data allocated by libpng in image->opaque, setting the pointer to
* NULL. May be called at any time after the structure is initialized.
*/
-#endif /* SIMPLIFIED_READ */
+#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
/* WRITE APIS
@@ -3299,21 +3202,18 @@ PNG_EXPORT(238, void, png_image_free,
* values do not correspond to the colors in sRGB.
* colormap_entries: set to the number of entries in the color-map (0 to 256)
*/
-#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
-PNG_EXPORT(239, int, png_image_write_to_file,
- (png_imagep image,
- const char *file, int convert_to_8bit, const void *buffer,
- png_int_32 row_stride, const void *colormap));
+PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
+ const char *file, int convert_to_8bit, const void *buffer,
+ png_int_32 row_stride, const void *colormap));
/* Write the image to the named file. */
-PNG_EXPORT(240, int, png_image_write_to_stdio,
- (png_imagep image,
- FILE *file, int convert_to_8_bit, const void *buffer,
- png_int_32 row_stride, const void *colormap));
- /* Write the image to the given FILE object. */
-#endif /* SIMPLIFIED_WRITE_STDIO */
+// 4j studios: callback support
+PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+ int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap, /*begin 4j change*/ png_rw_ptr write_fn, png_flush_ptr flush_fn /*end 4j change*/));
+ /* Write the image to the given (FILE*). */
-/* With all write APIs if image is in one of the linear formats with 16-bit
+/* With both write APIs if image is in one of the linear formats with 16-bit
* data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
* gamma encoded according to the sRGB specification, otherwise a 16-bit linear
* encoded PNG file is written.
@@ -3325,113 +3225,26 @@ PNG_EXPORT(240, int, png_image_write_to_stdio,
*
* With all APIs row_stride is handled as in the read APIs - it is the spacing
* from one row to the next in component sized units (1 or 2 bytes) and if
- * negative indicates a bottom-up row layout in the buffer. If row_stride is
- * zero, libpng will calculate it for you from the image width and number of
- * channels.
+ * negative indicates a bottom-up row layout in the buffer.
*
- * Note that the write API does not support interlacing, sub-8-bit pixels or
- * most ancillary chunks. If you need to write text chunks (e.g. for copyright
- * notices) you need to use one of the other APIs.
+ * Note that the write API does not support interlacing or sub-8-bit pixels.
*/
-
-PNG_EXPORT(245, int, png_image_write_to_memory,
- (png_imagep image,
- void *memory, png_alloc_size_t * PNG_RESTRICT memory_bytes,
- int convert_to_8_bit,
- const void *buffer, png_int_32 row_stride, const void *colormap));
- /* Write the image to the given memory buffer. The function both writes the
- * whole PNG data stream to *memory and updates *memory_bytes with the count
- * of bytes written.
- *
- * 'memory' may be NULL. In this case *memory_bytes is not read however on
- * success the number of bytes which would have been written will still be
- * stored in *memory_bytes. On failure *memory_bytes will contain 0.
- *
- * If 'memory' is not NULL it must point to memory[*memory_bytes] of
- * writeable memory.
- *
- * If the function returns success memory[*memory_bytes] (if 'memory' is not
- * NULL) contains the written PNG data. *memory_bytes will always be less
- * than or equal to the original value.
- *
- * If the function returns false and *memory_bytes was not changed an error
- * occurred during write. If *memory_bytes was changed, or is not 0 if
- * 'memory' was NULL, the write would have succeeded but for the memory
- * buffer being too small. *memory_bytes contains the required number of
- * bytes and will be bigger that the original value.
- */
-
-#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
- row_stride, colormap)\
- png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
- row_stride, colormap)
- /* Return the amount of memory in 'size' required to compress this image.
- * The png_image structure 'image' must be filled in as in the above
- * function and must not be changed before the actual write call, the buffer
- * and all other parameters must also be identical to that in the final
- * write call. The 'size' variable need not be initialized.
- *
- * NOTE: the macro returns true/false, if false is returned 'size' will be
- * set to zero and the write failed and probably will fail if tried again.
- */
-
-/* You can pre-allocate the buffer by making sure it is of sufficient size
- * regardless of the amount of compression achieved. The buffer size will
- * always be bigger than the original image and it will never be filled. The
- * following macros are provided to assist in allocating the buffer.
- */
-#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
- /* The number of uncompressed bytes in the PNG byte encoding of the image;
- * uncompressing the PNG IDAT data will give this number of bytes.
- *
- * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
- * macro can because of the extra bytes used in the PNG byte encoding. You
- * need to avoid this macro if your image size approaches 2^30 in width or
- * height. The same goes for the remainder of these macros; they all produce
- * bigger numbers than the actual in-memory image size.
- */
-#ifndef PNG_ZLIB_MAX_SIZE
-# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
- /* An upper bound on the number of compressed bytes given 'b' uncompressed
- * bytes. This is based on deflateBounds() in zlib; different
- * implementations of zlib compression may conceivably produce more data so
- * if your zlib implementation is not zlib itself redefine this macro
- * appropriately.
- */
-#endif
-
-#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
- PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
- /* An upper bound on the size of the data in the PNG IDAT chunks. */
-
-#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
- ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
- (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
- 12U+3U*(image).colormap_entries/*PLTE data*/+\
- (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
- 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
- 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
- /* A helper for the following macro; if your compiler cannot handle the
- * following macro use this one with the result of
- * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
- * compilers should handle this just fine.)
- */
-
-#define PNG_IMAGE_PNG_SIZE_MAX(image)\
- PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
- /* An upper bound on the total length of the PNG data stream for 'image'.
- * The result is of type png_alloc_size_t, on 32-bit systems this may
- * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
- * run out of buffer space but return a corrected size which should work.
- */
-#endif /* SIMPLIFIED_WRITE */
+#endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */
/*******************************************************************************
* END OF SIMPLIFIED API
******************************************************************************/
-#endif /* SIMPLIFIED_{READ|WRITE} */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+PNG_EXPORT(242, void, png_set_check_for_invalid_index,
+ (png_structrp png_ptr, int allowed));
+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
+ png_const_infop info_ptr));
+# endif
+#endif /* CHECK_FOR_INVALID_INDEX */
/*******************************************************************************
- * Section 6: IMPLEMENTATION OPTIONS
+ * IMPLEMENTATION OPTIONS
*******************************************************************************
*
* Support for arbitrary implementation-specific optimizations. The API allows
@@ -3439,7 +3252,7 @@ PNG_EXPORT(245, int, png_image_write_to_memory,
* option and 'onoff' is 0 (off) or non-0 (on). The value returned is given
* by the PNG_OPTION_ defines below.
*
- * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions,
+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
* are detected at run time, however sometimes it may be impossible
* to do this in user mode, in which case it is necessary to discover
* the capabilities in an OS specific way. Such capabilities are
@@ -3452,45 +3265,10 @@ PNG_EXPORT(245, int, png_image_write_to_memory,
* selected at run time.
*/
#ifdef PNG_SET_OPTION_SUPPORTED
-
-/* HARDWARE: ARM Neon SIMD instructions supported */
#ifdef PNG_ARM_NEON_API_SUPPORTED
-# define PNG_ARM_NEON 0
+# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */
#endif
-
-/* SOFTWARE: Force maximum window */
-#define PNG_MAXIMUM_INFLATE_WINDOW 2
-
-/* SOFTWARE: Check ICC profile for sRGB */
-#define PNG_SKIP_sRGB_CHECK_PROFILE 4
-
-/* HARDWARE: MIPS MSA SIMD instructions supported */
-#ifdef PNG_MIPS_MSA_API_SUPPORTED
-# define PNG_MIPS_MSA 6
-#endif
-
-/* SOFTWARE: Disable Adler32 check on IDAT */
-#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
-# define PNG_IGNORE_ADLER32 8
-#endif
-
-/* HARDWARE: PowerPC VSX SIMD instructions supported */
-#ifdef PNG_POWERPC_VSX_API_SUPPORTED
-# define PNG_POWERPC_VSX 10
-#endif
-
-/* HARDWARE: MIPS MMI SIMD instructions supported */
-#ifdef PNG_MIPS_MMI_API_SUPPORTED
-# define PNG_MIPS_MMI 12
-#endif
-
-/* HARDWARE: RISC-V RVV SIMD instructions supported */
-#ifdef PNG_RISCV_RVV_API_SUPPORTED
-# define PNG_RISCV_RVV 14
-#endif
-
-/* Next option - numbers must be even */
-#define PNG_OPTION_NEXT 16
+#define PNG_OPTION_NEXT 2 /* Next option - numbers must be even */
/* Return values: NOTE: there are four values and 'off' is *not* zero */
#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */
@@ -3500,21 +3278,22 @@ PNG_EXPORT(245, int, png_image_write_to_memory,
PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
int onoff));
-#endif /* SET_OPTION */
+#endif
/*******************************************************************************
- * END OF HARDWARE AND SOFTWARE OPTIONS
+ * END OF HARDWARE OPTIONS
******************************************************************************/
-/* Maintainer: Put new public prototypes here ^, in libpng.3, in project
- * defs, and in scripts/symbols.def.
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project
+ * defs, scripts/pnglibconf.h, and scripts/pnglibconf.h.prebuilt
*/
/* The last ordinal number (this is the *last* one already used; the next
- * one to use is one more than this.)
+ * one to use is one more than this.) Maintainer, remember to add an entry to
+ * scripts/symbols.def as well.
*/
#ifdef PNG_EXPORT_LAST_ORDINAL
- PNG_EXPORT_LAST_ORDINAL(259);
+ PNG_EXPORT_LAST_ORDINAL(244);
#endif
#ifdef __cplusplus
diff --git a/Windows_Libs/Dev/Render/libpng/pngconf.h b/Windows_Libs/Dev/Render/libpng/pngconf.h
index 4508452..31f9967 100644
--- a/Windows_Libs/Dev/Render/libpng/pngconf.h
+++ b/Windows_Libs/Dev/Render/libpng/pngconf.h
@@ -1,17 +1,19 @@
-/* pngconf.h - machine-configurable file for libpng
+
+/* pngconf.h - machine configurable file for libpng
*
- * libpng version 1.6.55
+ * libpng version 1.6.2 - April 25, 2013
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
- * Any machine specific code is near the front of this file, so if you
+ */
+
+/* Any machine specific code is near the front of this file, so if you
* are configuring libpng for a machine, you may want to read the section
* starting here down to where it starts to typedef png_color, png_text,
* and png_info.
@@ -20,6 +22,26 @@
#ifndef PNGCONF_H
#define PNGCONF_H
+/* To do: Do all of this in scripts/pnglibconf.dfa */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+# ifdef PNG_USER_WIDTH_MAX
+# undef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000L
+# endif
+# ifdef PNG_USER_HEIGHT_MAX
+# undef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000L
+# endif
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+# undef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 4000000L
+# endif
+# ifdef PNG_USER_CHUNK_CACHE_MAX
+# undef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 128
+# endif
+#endif
+
#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
@@ -57,13 +79,14 @@
#endif /* PNG_BUILDING_SYMBOL_TABLE */
-/* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
- * using PNG_NO_CONST. This is no longer supported.
+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
+ * PNG_NO_CONST; this is no longer supported except for data declarations which
+ * apparently still cause problems in 2011 on some compilers.
*/
#define PNG_CONST const /* backward compatibility only */
-/* This controls optimization of the reading of 16-bit and 32-bit
- * values from PNG files. It can be set on a per-app-file basis: it
+/* This controls optimization of the reading of 16 and 32 bit values
+ * from PNG files. It can be set on a per-app-file basis - it
* just changes whether a macro is used when the function is called.
* The library builder sets the default; if read functions are not
* built into the library the macro implementation is forced on.
@@ -87,7 +110,7 @@
/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
* against legacy (pre ISOC90) compilers that did not understand function
- * prototypes. [Deprecated.]
+ * prototypes. It is not required for modern C compilers.
*/
#ifndef PNGARG
# define PNGARG(arglist) arglist
@@ -126,7 +149,7 @@
*
* These cases only differ if the operating system does not use the C
* calling convention, at present this just means the above cases
- * (x86 DOS/Windows systems) and, even then, this does not apply to
+ * (x86 DOS/Windows sytems) and, even then, this does not apply to
* Cygwin running on those systems.
*
* Note that the value must be defined in pnglibconf.h so that what
@@ -179,35 +202,35 @@
* compiler-specific macros to the values required to change the calling
* conventions of the various functions.
*/
-#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \
- defined(__CYGWIN__)
+#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
+ defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
/* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
* MinGW on any architecture currently supported by Windows. Also includes
* Watcom builds but these need special treatment because they are not
* compatible with GCC or Visual C because of different calling conventions.
*/
# if PNG_API_RULE == 2
- /* If this line results in an error, either because __watcall is not
- * understood or because of a redefine just below you cannot use *this*
- * build of the library with the compiler you are using. *This* build was
- * build using Watcom and applications must also be built using Watcom!
- */
+ /* If this line results in an error, either because __watcall is not
+ * understood or because of a redefine just below you cannot use *this*
+ * build of the library with the compiler you are using. *This* build was
+ * build using Watcom and applications must also be built using Watcom!
+ */
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
- /* If this line results in an error __stdcall is not understood and
- * PNG_API_RULE should not have been set to '1'.
- */
+ /* If this line results in an error __stdcall is not understood and
+ * PNG_API_RULE should not have been set to '1'.
+ */
# define PNGAPI __stdcall
# endif
# else
- /* An older compiler, or one not detected (erroneously) above,
- * if necessary override on the command line to get the correct
- * variants for the compiler.
- */
+ /* An older compiler, or one not detected (erroneously) above,
+ * if necessary override on the command line to get the correct
+ * variants for the compiler.
+ */
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
@@ -215,25 +238,36 @@
# define PNGAPI _stdcall
# endif
# endif /* compiler/api */
-
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
-# error PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed
+# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
# endif
-# define PNG_DLL_EXPORT __declspec(dllexport)
-# ifndef PNG_DLL_IMPORT
-# define PNG_DLL_IMPORT __declspec(dllimport)
-# endif
+# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
+ (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
+ /* older Borland and MSC
+ * compilers used '__export' and required this to be after
+ * the type.
+ */
+# ifndef PNG_EXPORT_TYPE
+# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
+# endif
+# define PNG_DLL_EXPORT __export
+# else /* newer compiler */
+# define PNG_DLL_EXPORT __declspec(dllexport)
+# ifndef PNG_DLL_IMPORT
+# define PNG_DLL_IMPORT __declspec(dllimport)
+# endif
+# endif /* compiler */
#else /* !Windows */
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
- /* Use the defaults, or define PNG*API on the command line (but
- * this will have to be done for every compile!)
- */
+ /* Use the defaults, or define PNG*API on the command line (but
+ * this will have to be done for every compile!)
+ */
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
@@ -254,7 +288,7 @@
*/
#ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
- /* This forces use of a DLL, disallowing static linking */
+ /* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
@@ -282,11 +316,11 @@
* table entries, so we discard it here. See the .dfn files in the
* scripts directory.
*/
-
#ifndef PNG_EXPORTA
-# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
- PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), args, \
- PNG_LINKAGE_API attributes)
+
+# define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
+ extern attributes)
#endif
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
@@ -294,7 +328,7 @@
*/
#define PNG_EMPTY /*empty list*/
-#define PNG_EXPORT(ordinal, type, name, args) \
+#define PNG_EXPORT(ordinal, type, name, args)\
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
/* Use PNG_REMOVED to comment out a removed interface. */
@@ -303,7 +337,7 @@
#endif
#ifndef PNG_CALLBACK
-# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) args
+# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
#endif
/* Support for compiler specific function attributes. These are used
@@ -326,33 +360,7 @@
* version 1.2.41. Disabling these removes the warnings but may also produce
* less efficient code.
*/
-# if defined(__clang__) && defined(__has_attribute)
- /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
-# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
-# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
-# endif
-# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
-# define PNG_NORETURN __attribute__((__noreturn__))
-# endif
-# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
-# define PNG_ALLOCATED __attribute__((__malloc__))
-# endif
-# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
-# define PNG_DEPRECATED __attribute__((__deprecated__))
-# endif
-# if !defined(PNG_PRIVATE)
-# ifdef __has_extension
-# if __has_extension(attribute_unavailable_with_message)
-# define PNG_PRIVATE __attribute__((__unavailable__(\
- "This function is not exported by libpng.")))
-# endif
-# endif
-# endif
-# ifndef PNG_RESTRICT
-# define PNG_RESTRICT __restrict
-# endif
-
-# elif defined(__GNUC__)
+# if defined(__GNUC__)
# ifndef PNG_USE_RESULT
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
@@ -375,12 +383,12 @@
__attribute__((__deprecated__))
# endif
# endif
-# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+# if ((__GNUC__ != 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
-# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
-# endif /* __GNUC__ >= 3 */
+# endif /* __GNUC__ == 3.0 */
+# endif /* __GNUC__ >= 3 */
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
# ifndef PNG_USE_RESULT
@@ -410,7 +418,7 @@
# ifndef PNG_RESTRICT
# define PNG_RESTRICT __restrict
# endif
-# endif
+# endif /* _MSC_VER */
#endif /* PNG_PEDANTIC_WARNINGS */
#ifndef PNG_DEPRECATED
@@ -431,7 +439,6 @@
#ifndef PNG_RESTRICT
# define PNG_RESTRICT /* The C99 "restrict" feature */
#endif
-
#ifndef PNG_FP_EXPORT /* A floating point API. */
# ifdef PNG_FLOATING_POINT_SUPPORTED
# define PNG_FP_EXPORT(ordinal, type, name, args)\
@@ -467,7 +474,7 @@
#if CHAR_BIT == 8 && UCHAR_MAX == 255
typedef unsigned char png_byte;
#else
-# error libpng requires 8-bit bytes
+# error "libpng requires 8 bit bytes"
#endif
#if INT_MIN == -32768 && INT_MAX == 32767
@@ -475,7 +482,7 @@
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
typedef short png_int_16;
#else
-# error libpng requires a signed 16-bit integer type
+# error "libpng requires a signed 16 bit type"
#endif
#if UINT_MAX == 65535
@@ -483,7 +490,7 @@
#elif USHRT_MAX == 65535
typedef unsigned short png_uint_16;
#else
-# error libpng requires an unsigned 16-bit integer type
+# error "libpng requires an unsigned 16 bit type"
#endif
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
@@ -491,21 +498,19 @@
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
typedef long int png_int_32;
#else
-# error libpng requires a signed 32-bit (or longer) integer type
+# error "libpng requires a signed 32 bit (or more) type"
#endif
-#if UINT_MAX > 4294967294U
+#if UINT_MAX > 4294967294
typedef unsigned int png_uint_32;
-#elif ULONG_MAX > 4294967294U
+#elif ULONG_MAX > 4294967294
typedef unsigned long int png_uint_32;
#else
-# error libpng requires an unsigned 32-bit (or longer) integer type
+# error "libpng requires an unsigned 32 bit (or more) type"
#endif
-/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
- * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
- * behavior of sizeof and ptrdiff_t are required.
- * The legacy typedefs are provided here for backwards compatibility.
+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
*/
typedef size_t png_size_t;
typedef ptrdiff_t png_ptrdiff_t;
@@ -526,12 +531,13 @@ typedef ptrdiff_t png_ptrdiff_t;
# endif
#endif
-/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
- * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are
- * not necessary; in fact, it is recommended not to use them at all, so that
- * the compiler can complain when something turns out to be problematic.
+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
+ * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to
+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use
+ * them at all so that the compiler can complain when something turns out to be
+ * problematic.
*
- * Casts in the other direction (from png_alloc_size_t to size_t or
+ * Casts in the other direction (from png_alloc_size_t to png_size_t or
* png_uint_32) should be explicitly applied; however, we do not expect to
* encounter practical situations that require such conversions.
*
@@ -541,7 +547,7 @@ typedef ptrdiff_t png_ptrdiff_t;
#ifdef PNG_SMALL_SIZE_T
typedef png_uint_32 png_alloc_size_t;
#else
- typedef size_t png_alloc_size_t;
+ typedef png_size_t png_alloc_size_t;
#endif
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
@@ -577,8 +583,12 @@ typedef char * png_charp;
typedef const char * png_const_charp;
typedef png_fixed_point * png_fixed_point_p;
typedef const png_fixed_point * png_const_fixed_point_p;
-typedef size_t * png_size_tp;
-typedef const size_t * png_const_size_tp;
+typedef png_size_t * png_size_tp;
+typedef const png_size_t * png_const_size_tp;
+
+#ifdef PNG_STDIO_SUPPORTED
+typedef FILE * png_FILE_p;
+#endif
#ifdef PNG_FLOATING_POINT_SUPPORTED
typedef double * png_doublep;
@@ -601,15 +611,6 @@ typedef double * * png_doublepp;
/* Pointers to pointers to pointers; i.e., pointer to array */
typedef char * * * png_charppp;
-#ifdef PNG_STDIO_SUPPORTED
-/* With PNG_STDIO_SUPPORTED it was possible to use I/O streams that were
- * not necessarily stdio FILE streams, to allow building Windows applications
- * before Win32 and Windows CE applications before WinCE 3.0, but that kind
- * of support has long been discontinued.
- */
-typedef FILE * png_FILE_p; /* [Deprecated] */
-#endif
-
#endif /* PNG_BUILDING_SYMBOL_TABLE */
#endif /* PNGCONF_H */
diff --git a/Windows_Libs/Dev/Render/libpng/pngdebug.h b/Windows_Libs/Dev/Render/libpng/pngdebug.h
index 0337918..16f81fd 100644
--- a/Windows_Libs/Dev/Render/libpng/pngdebug.h
+++ b/Windows_Libs/Dev/Render/libpng/pngdebug.h
@@ -1,19 +1,17 @@
-/* pngdebug.h - internal debugging macros for libpng
+
+/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.5.0 [January 6, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
-#ifndef PNGPRIV_H
-# error This file must not be included by applications; please include
-#endif
-
/* Define PNG_DEBUG at compile time for debugging information. Higher
* numbers for PNG_DEBUG mean more debugging information. This has
* only been added since version 0.95 so it is not implemented throughout
@@ -27,7 +25,7 @@
* (actually ((void)0)).
*
* level: level of detail of message, starting at 0. A level 'n'
- * message is preceded by 'n' 3-space indentations (not implemented
+ * message is preceded by 'n' tab characters (not implemented
* on Microsoft compilers unless PNG_DEBUG_FILE is also
* defined, to allow debug DLL compilation with no standard IO).
* message: a printf(3) style text string. A trailing '\n' is added
@@ -38,6 +36,9 @@
#define PNGDEBUG_H
/* These settings control the formatting of messages in png.c and pngerror.c */
/* Moved to pngdebug.h at 1.5.0 */
+# ifndef PNG_LITERAL_SHARP
+# define PNG_LITERAL_SHARP 0x23
+# endif
# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
# endif
@@ -76,29 +77,32 @@
# endif /* PNG_DEBUG_FILE */
# if (PNG_DEBUG > 1)
+/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
+ * non-ISO compilers
+ */
# ifdef __STDC__
# ifndef png_debug
# define png_debug(l,m) \
do { \
int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
- (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
} while (0)
# endif
# ifndef png_debug1
# define png_debug1(l,m,p1) \
do { \
int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
- (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
} while (0)
# endif
# ifndef png_debug2
# define png_debug2(l,m,p1,p2) \
do { \
int num_tabs=l; \
- fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
- (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
} while (0)
# endif
# else /* __STDC __ */
diff --git a/Windows_Libs/Dev/Render/libpng/pngerror.c b/Windows_Libs/Dev/Render/libpng/pngerror.c
index 72dc20e..f469206 100644
--- a/Windows_Libs/Dev/Render/libpng/pngerror.c
+++ b/Windows_Libs/Dev/Render/libpng/pngerror.c
@@ -1,9 +1,10 @@
+
/* pngerror.c - stub functions for i/o and memory allocation
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -19,15 +20,14 @@
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
-static PNG_FUNCTION(void /* PRIVATE */,
-png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN);
+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
+ png_const_charp error_message)),PNG_NORETURN);
#ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */
-png_default_warning(png_const_structrp png_ptr,
- png_const_charp warning_message);
-#endif /* WARNINGS */
+png_default_warning PNGARG((png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called whenever there is a fatal error. This function
* should not be changed. If there is a need to handle errors differently,
@@ -37,8 +37,48 @@ png_default_warning(png_const_structrp png_ptr,
#ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr != NULL)
+ {
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+ {
+ if (*error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ for (offset = 1; offset<15; offset++)
+ if (error_message[offset] == ' ')
+ break;
+
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ int i;
+ for (i = 0; i < offset - 1; i++)
+ msg[i] = error_message[i + 1];
+ msg[i - 1] = '\0';
+ error_message = msg;
+ }
+
+ else
+ error_message += offset;
+ }
+
+ else
+ {
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ msg[0] = '0';
+ msg[1] = '\0';
+ error_message = msg;
+ }
+ }
+ }
+ }
+#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
error_message);
@@ -49,8 +89,7 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
}
#else
PNG_FUNCTION(void,PNGAPI
-png_err,(png_const_structrp png_ptr),
- PNG_NORETURN)
+png_err,(png_const_structrp png_ptr),PNG_NORETURN)
{
/* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
* erroneously as '\0', instead of the empty string "". This was
@@ -64,14 +103,14 @@ png_err,(png_const_structrp png_ptr),
use the default handler, which will not return. */
png_default_error(png_ptr, "");
}
-#endif /* ERROR_TEXT */
+#endif /* PNG_ERROR_TEXT_SUPPORTED */
/* Utility to safely appends strings to a buffer. This never errors out so
* error checking is not required in the caller.
*/
size_t
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
- png_const_charp string)
+ png_const_charp string)
{
if (buffer != NULL && pos < bufsize)
{
@@ -92,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos,
*/
png_charp
png_format_number(png_const_charp start, png_charp end, int format,
- png_alloc_size_t number)
+ png_alloc_size_t number)
{
int count = 0; /* number of digits output */
int mincount = 1; /* minimum number required */
@@ -113,7 +152,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_fixed:
/* Needs five digits (the fraction) */
mincount = 5;
- if (output != 0 || number % 10 != 0)
+ if (output || number % 10 != 0)
{
*--end = digits[number % 10];
output = 1;
@@ -124,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02u:
/* Expects at least 2 digits. */
mincount = 2;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case PNG_NUMBER_FORMAT_u:
*--end = digits[number % 10];
@@ -134,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02x:
/* This format expects at least two digits */
mincount = 2;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case PNG_NUMBER_FORMAT_x:
*--end = digits[number & 0xf];
@@ -150,13 +189,13 @@ png_format_number(png_const_charp start, png_charp end, int format,
++count;
/* Float a fixed number here: */
- if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
+ if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
{
/* End of the fraction, but maybe nothing was output? In that case
* drop the decimal point. If the number is a true zero handle that
* here.
*/
- if (output != 0)
+ if (output)
*--end = '.';
else if (number == 0) /* and !output */
*--end = '0';
@@ -177,9 +216,24 @@ void PNGAPI
png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
{
int offset = 0;
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+ {
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ for (offset = 1; offset < 15; offset++)
+ if (warning_message[offset] == ' ')
+ break;
+ }
+ }
+ }
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
- warning_message + offset);
+ warning_message + offset);
else
png_default_warning(png_ptr, warning_message + offset);
}
@@ -191,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
*/
void
png_warning_parameter(png_warning_parameters p, int number,
- png_const_charp string)
+ png_const_charp string)
{
if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
@@ -199,19 +253,19 @@ png_warning_parameter(png_warning_parameters p, int number,
void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
- png_alloc_size_t value)
+ png_alloc_size_t value)
{
- char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
}
void
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
- png_int_32 value)
+ png_int_32 value)
{
png_alloc_size_t u;
png_charp str;
- char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
/* Avoid overflow by doing the negate in a png_alloc_size_t: */
u = (png_alloc_size_t)value;
@@ -228,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
void
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
- png_const_charp message)
+ png_const_charp message)
{
/* The internal buffer is just 192 bytes - enough for all our messages,
* overflow doesn't happen because this code checks! If someone figures
@@ -301,13 +355,13 @@ png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
*/
png_warning(png_ptr, msg);
}
-#endif /* WARNINGS */
+#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
{
- if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
{
# ifdef PNG_READ_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
@@ -328,57 +382,44 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
# endif
png_error(png_ptr, error_message);
}
-
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(error_message)
-# endif
}
void /* PRIVATE */
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
{
- if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
- png_warning(png_ptr, error_message);
- else
- png_error(png_ptr, error_message);
-
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(error_message)
-# endif
+ if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
}
void /* PRIVATE */
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
{
- if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
- png_warning(png_ptr, error_message);
- else
- png_error(png_ptr, error_message);
-
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(error_message)
-# endif
+ if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
}
#endif /* BENIGN_ERRORS */
-#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
-#if defined(PNG_WARNINGS_SUPPORTED) || \
- (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
- * which is used to prefix the message. The message is limited in length
- * to 63 bytes. The name characters are output as hex digits wrapped in []
+ * this is used to prefix the message. The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
-static const char png_digit[16] = {
+static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited be profile_error in png.c */
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
static void /* PRIVATE */
-png_format_buffer(png_const_structrp png_ptr, png_charp buffer,
- png_const_charp error_message)
+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
+ error_message)
{
png_uint_32 chunk_name = png_ptr->chunk_name;
int iout = 0, ishift = 24;
@@ -388,7 +429,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer,
int c = (int)(chunk_name >> ishift) & 0xff;
ishift -= 8;
- if (isnonalpha(c) != 0)
+ if (isnonalpha(c))
{
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
@@ -419,12 +460,12 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer,
buffer[iout] = '\0';
}
}
-#endif /* WARNINGS || ERROR_TEXT */
+#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
@@ -436,7 +477,7 @@ png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
png_error(png_ptr, msg);
}
}
-#endif /* READ && ERROR_TEXT */
+#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
#ifdef PNG_WARNINGS_SUPPORTED
void PNGAPI
@@ -452,39 +493,31 @@ png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
png_warning(png_ptr, msg);
}
}
-#endif /* WARNINGS */
+#endif /* PNG_WARNINGS_SUPPORTED */
#ifdef PNG_READ_SUPPORTED
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
void PNGAPI
-png_chunk_benign_error(png_const_structrp png_ptr,
- png_const_charp error_message)
+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+ error_message)
{
- if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
png_chunk_warning(png_ptr, error_message);
else
png_chunk_error(png_ptr, error_message);
-
-# ifndef PNG_ERROR_TEXT_SUPPORTED
- PNG_UNUSED(error_message)
-# endif
}
#endif
-#endif /* READ */
+#endif /* PNG_READ_SUPPORTED */
void /* PRIVATE */
png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
{
-# ifndef PNG_WARNINGS_SUPPORTED
- PNG_UNUSED(message)
-# endif
-
/* This is always supported, but for just read or just write it
* unconditionally does the right thing.
*/
# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
# endif
# ifdef PNG_READ_SUPPORTED
@@ -498,7 +531,7 @@ png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
# endif
# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
- else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ else if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
# endif
# ifdef PNG_WRITE_SUPPORTED
@@ -515,21 +548,19 @@ png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
#ifdef PNG_ERROR_TEXT_SUPPORTED
#ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_FUNCTION(void,
-png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),
- PNG_NORETURN)
+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
{
# define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1)
- unsigned int iin;
+ int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
memcpy(msg, fixed_message, fixed_message_ln);
iin = 0;
- if (name != NULL)
- while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
- {
- msg[fixed_message_ln + iin] = name[iin];
- ++iin;
- }
+ if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
+ {
+ msg[fixed_message_ln + iin] = name[iin];
+ ++iin;
+ }
msg[fixed_message_ln + iin] = 0;
png_error(png_ptr, msg);
}
@@ -567,7 +598,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
else
{
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
- png_malloc_warn(png_ptr, jmp_buf_size));
+ png_malloc_warn(png_ptr, jmp_buf_size));
if (png_ptr->jmp_buf_ptr == NULL)
return NULL; /* new NULL return on OOM */
@@ -656,12 +687,45 @@ png_free_jmpbuf(png_structrp png_ptr)
*/
static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
- PNG_NORETURN)
+ PNG_NORETURN)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "libpng error: %s", error_message ? error_message :
- "undefined");
- fprintf(stderr, PNG_STRING_NEWLINE);
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ /* Check on NULL only added in 1.5.4 */
+ if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ char error_number[16];
+ for (offset = 0; offset<15; offset++)
+ {
+ error_number[offset] = error_message[offset + 1];
+ if (error_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ error_number[offset - 1] = '\0';
+ fprintf(stderr, "libpng error no. %s: %s",
+ error_number, error_message + offset + 1);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng error: %s, offset=%d",
+ error_message, offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+#endif
+ {
+ fprintf(stderr, "libpng error: %s", error_message ? error_message :
+ "undefined");
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
#else
PNG_UNUSED(error_message) /* Make compiler happy */
#endif
@@ -669,24 +733,14 @@ png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
}
PNG_FUNCTION(void,PNGAPI
-png_longjmp,(png_const_structrp png_ptr, int val),
- PNG_NORETURN)
+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
{
#ifdef PNG_SETJMP_SUPPORTED
- if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
- png_ptr->jmp_buf_ptr != NULL)
+ if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(val)
#endif
- /* If control reaches this point, png_longjmp() must not return. The only
- * choice is to terminate the whole process (or maybe the thread); to do
- * this the ANSI-C abort() function is used unless a different method is
- * implemented by overriding the default configuration setting for
- * PNG_ABORT().
- */
+ /* Here if not setjmp support or if png_ptr is null. */
PNG_ABORT();
}
@@ -700,14 +754,46 @@ static void /* PRIVATE */
png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "libpng warning: %s", warning_message);
- fprintf(stderr, PNG_STRING_NEWLINE);
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ int offset;
+ char warning_number[16];
+ for (offset = 0; offset < 15; offset++)
+ {
+ warning_number[offset] = warning_message[offset + 1];
+ if (warning_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ warning_number[offset + 1] = '\0';
+ fprintf(stderr, "libpng warning no. %s: %s",
+ warning_number, warning_message + offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng warning: %s",
+ warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+# endif
+
+ {
+ fprintf(stderr, "libpng warning: %s", warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
#else
PNG_UNUSED(warning_message) /* Make compiler happy */
#endif
PNG_UNUSED(png_ptr) /* Make compiler happy */
}
-#endif /* WARNINGS */
+#endif /* PNG_WARNINGS_SUPPORTED */
/* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT
@@ -741,7 +827,7 @@ png_get_error_ptr(png_const_structrp png_ptr)
if (png_ptr == NULL)
return NULL;
- return (png_voidp)png_ptr->error_ptr;
+ return ((png_voidp)png_ptr->error_ptr);
}
@@ -749,8 +835,12 @@ png_get_error_ptr(png_const_structrp png_ptr)
void PNGAPI
png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
{
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(strip_mode)
+ if (png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
+ PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
}
#endif
@@ -760,11 +850,11 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
* possible to implement without setjmp support just so long as there is some
* way to handle the error return here:
*/
-PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
-png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
- PNG_NORETURN)
+PNG_FUNCTION(void /* PRIVATE */,
+png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
+ PNG_NORETURN)
{
- png_const_structrp png_ptr = png_nonconst_ptr;
+ const png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* An error is always logged here, overwriting anything (typically a warning)
@@ -785,7 +875,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
/* Missing longjmp buffer, the following is to help debugging: */
{
size_t pos = png_safecat(image->message, (sizeof image->message), 0,
- "bad longjmp: ");
+ "bad longjmp: ");
png_safecat(image->message, (sizeof image->message), pos,
error_message);
}
@@ -796,10 +886,10 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
}
#ifdef PNG_WARNINGS_SUPPORTED
-void /* PRIVATE */ PNGCBAPI
+void /* PRIVATE */
png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
{
- png_const_structrp png_ptr = png_nonconst_ptr;
+ const png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* A warning is only logged if there is no prior warning or error. */
@@ -812,39 +902,31 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
#endif
int /* PRIVATE */
-png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg)
+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
{
- const png_voidp saved_error_buf = image->opaque->error_buf;
+ volatile png_imagep image = image_in;
+ volatile int result;
+ volatile png_voidp saved_error_buf;
jmp_buf safe_jmpbuf;
- /* Safely execute function(arg), with png_error returning back here. */
- if (setjmp(safe_jmpbuf) == 0)
+ /* Safely execute function(arg) with png_error returning to this function. */
+ saved_error_buf = image->opaque->error_buf;
+ result = setjmp(safe_jmpbuf) == 0;
+
+ if (result)
{
- int result;
image->opaque->error_buf = safe_jmpbuf;
result = function(arg);
- image->opaque->error_buf = saved_error_buf;
-
- if (result)
- return 1; /* success */
}
- /* The function failed either because of a caught png_error and a regular
- * return of false above or because of an uncaught png_error from the
- * function itself. Ensure that the error_buf is always set back to the
- * value saved above:
- */
image->opaque->error_buf = saved_error_buf;
- /* On the final false return, when about to return control to the caller, the
- * image is freed (png_image_free does this check but it is duplicated here
- * for clarity:
- */
- if (saved_error_buf == NULL)
+ /* And do the cleanup prior to any failure return. */
+ if (!result)
png_image_free(image);
- return 0; /* failure */
+ return result;
}
-#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
-#endif /* READ || WRITE */
+#endif /* SIMPLIFIED READ/WRITE */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngget.c b/Windows_Libs/Dev/Render/libpng/pngget.c
index 9c7e8a1..aca63a9 100644
--- a/Windows_Libs/Dev/Render/libpng/pngget.c
+++ b/Windows_Libs/Dev/Render/libpng/pngget.c
@@ -1,9 +1,10 @@
+
/* pngget.c - retrieval of values from info struct
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -20,29 +21,18 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 flag)
{
if (png_ptr != NULL && info_ptr != NULL)
- {
-#ifdef PNG_READ_tRNS_SUPPORTED
- /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the
- * 'valid' flag for the detection of duplicate chunks. Do not report a
- * valid tRNS chunk in this case.
- */
- if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0)
- return 0;
-#endif
+ return(info_ptr->valid & flag);
- return info_ptr->valid & flag;
- }
-
- return 0;
+ return(0);
}
-size_t PNGAPI
+png_size_t PNGAPI
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return info_ptr->rowbytes;
+ return(info_ptr->rowbytes);
- return 0;
+ return(0);
}
#ifdef PNG_INFO_IMAGE_SUPPORTED
@@ -50,9 +40,9 @@ png_bytepp PNGAPI
png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return info_ptr->row_pointers;
+ return(info_ptr->row_pointers);
- return 0;
+ return(0);
}
#endif
@@ -64,7 +54,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->width;
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
@@ -73,7 +63,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->height;
- return 0;
+ return (0);
}
png_byte PNGAPI
@@ -82,7 +72,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->bit_depth;
- return 0;
+ return (0);
}
png_byte PNGAPI
@@ -91,7 +81,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->color_type;
- return 0;
+ return (0);
}
png_byte PNGAPI
@@ -100,7 +90,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->filter_type;
- return 0;
+ return (0);
}
png_byte PNGAPI
@@ -109,7 +99,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->interlace_type;
- return 0;
+ return (0);
}
png_byte PNGAPI
@@ -118,93 +108,82 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->compression_type;
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
-png_get_x_pixels_per_meter(png_const_structrp png_ptr,
- png_const_inforp info_ptr)
+png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
- png_debug(1, "in png_get_x_pixels_per_meter");
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function",
+ "png_get_x_pixels_per_meter");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
- {
- if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
- return info_ptr->x_pixels_per_unit;
- }
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return (info_ptr->x_pixels_per_unit);
+ }
#endif
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
-png_get_y_pixels_per_meter(png_const_structrp png_ptr,
- png_const_inforp info_ptr)
+png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
- png_debug(1, "in png_get_y_pixels_per_meter");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
+ png_debug1(1, "in %s retrieval function",
+ "png_get_y_pixels_per_meter");
+
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
- return info_ptr->y_pixels_per_unit;
+ return (info_ptr->y_pixels_per_unit);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
- png_debug(1, "in png_get_pixels_per_meter");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
- return info_ptr->x_pixels_per_unit;
+ return (info_ptr->x_pixels_per_unit);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
#ifdef PNG_FLOATING_POINT_SUPPORTED
float PNGAPI
-png_get_pixel_aspect_ratio(png_const_structrp png_ptr,
- png_const_inforp info_ptr)
+png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
- png_debug(1, "in png_get_pixel_aspect_ratio");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
if (info_ptr->x_pixels_per_unit != 0)
- return (float)info_ptr->y_pixels_per_unit
- / (float)info_ptr->x_pixels_per_unit;
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
- return (float)0.0;
+ return ((float)0.0);
}
#endif
@@ -214,21 +193,20 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
png_const_inforp info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
- png_debug(1, "in png_get_pixel_aspect_ratio_fixed");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0 &&
- info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
- info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
- info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)
+ && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0
+ && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX
+ && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
{
png_fixed_point res;
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
+
/* The following casts work because a PNG 4 byte integer only has a valid
* range of 0..2^31-1; otherwise the cast might overflow.
*/
if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
- (png_int_32)info_ptr->x_pixels_per_unit) != 0)
+ (png_int_32)info_ptr->x_pixels_per_unit))
return res;
}
#else
@@ -244,80 +222,64 @@ png_int_32 PNGAPI
png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
- png_debug(1, "in png_get_x_offset_microns");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
- return info_ptr->x_offset;
+ return (info_ptr->x_offset);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
png_int_32 PNGAPI
png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
- png_debug(1, "in png_get_y_offset_microns");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
- return info_ptr->y_offset;
+ return (info_ptr->y_offset);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
png_int_32 PNGAPI
png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
- png_debug(1, "in png_get_x_offset_pixels");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
+
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
- return info_ptr->x_offset;
+ return (info_ptr->x_offset);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
png_int_32 PNGAPI
png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
- png_debug(1, "in png_get_y_offset_pixels");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
+
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
- return info_ptr->y_offset;
+ return (info_ptr->y_offset);
}
-#else
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(info_ptr)
#endif
- return 0;
+ return (0);
}
#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
@@ -345,8 +307,8 @@ ppi_from_ppm(png_uint_32 ppm)
*/
png_fixed_point result;
if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
- 5000) != 0)
- return (png_uint_32)result;
+ 5000))
+ return result;
/* Overflow. */
return 0;
@@ -375,18 +337,12 @@ png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
static png_fixed_point
png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
{
- /* Convert from meters * 1,000,000 to inches * 100,000, meters to
+ /* Convert from metres * 1,000,000 to inches * 100,000, meters to
* inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
* Notice that this can overflow - a warning is output and 0 is
* returned.
*/
- png_fixed_point result;
-
- if (png_muldiv(&result, microns, 500, 127) != 0)
- return result;
-
- png_warning(png_ptr, "fixed point overflow ignored");
- return 0;
+ return png_muldiv_warn(png_ptr, microns, 500, 127);
}
png_fixed_point PNGAPI
@@ -396,7 +352,7 @@ png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
return png_fixed_inches_from_microns(png_ptr,
png_get_x_offset_microns(png_ptr, info_ptr));
}
-#endif /* FIXED_POINT */
+#endif
#ifdef PNG_FIXED_POINT_SUPPORTED
png_fixed_point PNGAPI
@@ -437,11 +393,10 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_uint_32 retval = 0;
- png_debug1(1, "in %s retrieval function", "pHYs");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
@@ -467,23 +422,23 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
- return retval;
+ return (retval);
}
-#endif /* pHYs */
-#endif /* INCH_CONVERSIONS */
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */
/* png_get_channels really belongs in here, too, but it's been around longer */
-#endif /* EASY_ACCESS */
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
png_byte PNGAPI
png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return info_ptr->channels;
+ return(info_ptr->channels);
- return 0;
+ return (0);
}
#ifdef PNG_READ_SUPPORTED
@@ -491,28 +446,27 @@ png_const_bytep PNGAPI
png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
- return info_ptr->signature;
+ return(info_ptr->signature);
- return NULL;
+ return (NULL);
}
#endif
#ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
- png_color_16p *background)
+ png_color_16p *background)
{
- png_debug1(1, "in %s retrieval function", "bKGD");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
- background != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+ && background != NULL)
{
+ png_debug1(1, "in %s retrieval function", "bKGD");
+
*background = &(info_ptr->background);
- return PNG_INFO_bKGD;
+ return (PNG_INFO_bKGD);
}
- return 0;
+ return (0);
}
#endif
@@ -524,72 +478,92 @@ png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
# ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *whitex, double *whitey, double *redx, double *redy,
- double *greenx, double *greeny, double *bluex, double *bluey)
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
{
- png_debug1(1, "in %s retrieval function", "cHRM");
-
- /* PNGv3: this just returns the values store from the cHRM, if any. */
+ /* Quiet API change: this code used to only return the end points if a cHRM
+ * chunk was present, but the end points can also come from iCCP or sRGB
+ * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
+ * the png_set_ APIs merely check that set end points are mutually
+ * consistent.
+ */
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cHRM) != 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
{
- if (whitex != NULL)
- *whitex = png_float(png_ptr, info_ptr->cHRM.whitex, "cHRM wx");
- if (whitey != NULL)
- *whitey = png_float(png_ptr, info_ptr->cHRM.whitey, "cHRM wy");
- if (redx != NULL)
- *redx = png_float(png_ptr, info_ptr->cHRM.redx, "cHRM rx");
- if (redy != NULL)
- *redy = png_float(png_ptr, info_ptr->cHRM.redy, "cHRM ry");
- if (greenx != NULL)
- *greenx = png_float(png_ptr, info_ptr->cHRM.greenx, "cHRM gx");
- if (greeny != NULL)
- *greeny = png_float(png_ptr, info_ptr->cHRM.greeny, "cHRM gy");
- if (bluex != NULL)
- *bluex = png_float(png_ptr, info_ptr->cHRM.bluex, "cHRM bx");
- if (bluey != NULL)
- *bluey = png_float(png_ptr, info_ptr->cHRM.bluey, "cHRM by");
- return PNG_INFO_cHRM;
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (white_x != NULL)
+ *white_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+ if (white_y != NULL)
+ *white_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+ if (red_x != NULL)
+ *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
+ "cHRM red X");
+ if (red_y != NULL)
+ *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
+ "cHRM red Y");
+ if (green_x != NULL)
+ *green_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+ if (green_y != NULL)
+ *green_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+ if (blue_x != NULL)
+ *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
+ "cHRM blue X");
+ if (blue_y != NULL)
+ *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
+ "cHRM blue Y");
+ return (PNG_INFO_cHRM);
}
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *red_X, double *red_Y, double *red_Z, double *green_X,
- double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
- double *blue_Z)
+ double *red_X, double *red_Y, double *red_Z, double *green_X,
+ double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+ double *blue_Z)
{
- png_XYZ XYZ;
- png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
-
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cHRM) != 0 &&
- png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
{
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
+
if (red_X != NULL)
- *red_X = png_float(png_ptr, XYZ.red_X, "cHRM red X");
+ *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
+ "cHRM red X");
if (red_Y != NULL)
- *red_Y = png_float(png_ptr, XYZ.red_Y, "cHRM red Y");
+ *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
+ "cHRM red Y");
if (red_Z != NULL)
- *red_Z = png_float(png_ptr, XYZ.red_Z, "cHRM red Z");
+ *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
+ "cHRM red Z");
if (green_X != NULL)
- *green_X = png_float(png_ptr, XYZ.green_X, "cHRM green X");
+ *green_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
if (green_Y != NULL)
- *green_Y = png_float(png_ptr, XYZ.green_Y, "cHRM green Y");
+ *green_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
if (green_Z != NULL)
- *green_Z = png_float(png_ptr, XYZ.green_Z, "cHRM green Z");
+ *green_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
if (blue_X != NULL)
- *blue_X = png_float(png_ptr, XYZ.blue_X, "cHRM blue X");
+ *blue_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
if (blue_Y != NULL)
- *blue_Y = png_float(png_ptr, XYZ.blue_Y, "cHRM blue Y");
+ *blue_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
if (blue_Z != NULL)
- *blue_Z = png_float(png_ptr, XYZ.blue_Z, "cHRM blue Z");
- return PNG_INFO_cHRM;
+ *blue_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+ return (PNG_INFO_cHRM);
}
- return 0;
+ return (0);
}
# endif
@@ -602,52 +576,66 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z)
{
- png_XYZ XYZ;
- png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
-
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cHRM) != 0U &&
- png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
{
- if (int_red_X != NULL) *int_red_X = XYZ.red_X;
- if (int_red_Y != NULL) *int_red_Y = XYZ.red_Y;
- if (int_red_Z != NULL) *int_red_Z = XYZ.red_Z;
- if (int_green_X != NULL) *int_green_X = XYZ.green_X;
- if (int_green_Y != NULL) *int_green_Y = XYZ.green_Y;
- if (int_green_Z != NULL) *int_green_Z = XYZ.green_Z;
- if (int_blue_X != NULL) *int_blue_X = XYZ.blue_X;
- if (int_blue_Y != NULL) *int_blue_Y = XYZ.blue_Y;
- if (int_blue_Z != NULL) *int_blue_Z = XYZ.blue_Z;
- return PNG_INFO_cHRM;
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
+
+ if (int_red_X != NULL)
+ *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
+ if (int_red_Y != NULL)
+ *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
+ if (int_red_Z != NULL)
+ *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
+ if (int_green_X != NULL)
+ *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
+ if (int_green_Y != NULL)
+ *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
+ if (int_green_Z != NULL)
+ *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
+ if (int_blue_X != NULL)
+ *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
+ if (int_blue_Y != NULL)
+ *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
+ if (int_blue_Z != NULL)
+ *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
+ return (PNG_INFO_cHRM);
}
- return 0;
+ return (0);
}
png_uint_32 PNGAPI
png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_fixed_point *whitex, png_fixed_point *whitey, png_fixed_point *redx,
- png_fixed_point *redy, png_fixed_point *greenx, png_fixed_point *greeny,
- png_fixed_point *bluex, png_fixed_point *bluey)
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
{
png_debug1(1, "in %s retrieval function", "cHRM");
- /* PNGv3: this just returns the values store from the cHRM, if any. */
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cHRM) != 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
{
- if (whitex != NULL) *whitex = info_ptr->cHRM.whitex;
- if (whitey != NULL) *whitey = info_ptr->cHRM.whitey;
- if (redx != NULL) *redx = info_ptr->cHRM.redx;
- if (redy != NULL) *redy = info_ptr->cHRM.redy;
- if (greenx != NULL) *greenx = info_ptr->cHRM.greenx;
- if (greeny != NULL) *greeny = info_ptr->cHRM.greeny;
- if (bluex != NULL) *bluex = info_ptr->cHRM.bluex;
- if (bluey != NULL) *bluey = info_ptr->cHRM.bluey;
- return PNG_INFO_cHRM;
+ if (white_x != NULL)
+ *white_x = info_ptr->colorspace.end_points_xy.whitex;
+ if (white_y != NULL)
+ *white_y = info_ptr->colorspace.end_points_xy.whitey;
+ if (red_x != NULL)
+ *red_x = info_ptr->colorspace.end_points_xy.redx;
+ if (red_y != NULL)
+ *red_y = info_ptr->colorspace.end_points_xy.redy;
+ if (green_x != NULL)
+ *green_x = info_ptr->colorspace.end_points_xy.greenx;
+ if (green_y != NULL)
+ *green_y = info_ptr->colorspace.end_points_xy.greeny;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->colorspace.end_points_xy.bluex;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->colorspace.end_points_xy.bluey;
+ return (PNG_INFO_cHRM);
}
- return 0;
+ return (0);
}
# endif
#endif
@@ -660,15 +648,15 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "gAMA");
- /* PNGv3 compatibility: only report gAMA if it is really present. */
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_gAMA) != 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
+ file_gamma != NULL)
{
- if (file_gamma != NULL) *file_gamma = info_ptr->gamma;
- return PNG_INFO_gAMA;
+ *file_gamma = info_ptr->colorspace.gamma;
+ return (PNG_INFO_gAMA);
}
- return 0;
+ return (0);
}
# endif
@@ -679,17 +667,16 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "gAMA(float)");
- /* PNGv3 compatibility: only report gAMA if it is really present. */
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_gAMA) != 0)
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
+ file_gamma != NULL)
{
- if (file_gamma != NULL)
- *file_gamma = png_float(png_ptr, info_ptr->gamma, "gAMA");
-
- return PNG_INFO_gAMA;
+ *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
+ "png_get_gAMA");
+ return (PNG_INFO_gAMA);
}
- return 0;
+ return (0);
}
# endif
#endif
@@ -701,15 +688,14 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "sRGB");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sRGB) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+ && file_srgb_intent != NULL)
{
- if (file_srgb_intent != NULL)
- *file_srgb_intent = info_ptr->rendering_intent;
- return PNG_INFO_sRGB;
+ *file_srgb_intent = info_ptr->colorspace.rendering_intent;
+ return (PNG_INFO_sRGB);
}
- return 0;
+ return (0);
}
#endif
@@ -721,9 +707,9 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "iCCP");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
- name != NULL && profile != NULL && proflen != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+ && name != NULL && compression_type != NULL && profile != NULL &&
+ proflen != NULL)
{
*name = info_ptr->iccp_name;
*profile = info_ptr->iccp_profile;
@@ -731,12 +717,11 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
/* This is somewhat irrelevant since the profile data returned has
* actually been uncompressed.
*/
- if (compression_type != NULL)
- *compression_type = PNG_COMPRESSION_TYPE_BASE;
- return PNG_INFO_iCCP;
+ *compression_type = PNG_COMPRESSION_TYPE_BASE;
+ return (PNG_INFO_iCCP);
}
- return 0;
+ return (0);
}
#endif
@@ -745,174 +730,13 @@ int PNGAPI
png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
png_sPLT_tpp spalettes)
{
- png_debug1(1, "in %s retrieval function", "sPLT");
-
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
{
*spalettes = info_ptr->splt_palettes;
return info_ptr->splt_palettes_num;
}
- return 0;
-}
-#endif
-
-#ifdef PNG_cICP_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cICP(png_const_structrp png_ptr,
- png_const_inforp info_ptr, png_bytep colour_primaries,
- png_bytep transfer_function, png_bytep matrix_coefficients,
- png_bytep video_full_range_flag)
-{
- png_debug1(1, "in %s retrieval function", "cICP");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cICP) != 0 &&
- colour_primaries != NULL && transfer_function != NULL &&
- matrix_coefficients != NULL && video_full_range_flag != NULL)
- {
- *colour_primaries = info_ptr->cicp_colour_primaries;
- *transfer_function = info_ptr->cicp_transfer_function;
- *matrix_coefficients = info_ptr->cicp_matrix_coefficients;
- *video_full_range_flag = info_ptr->cicp_video_full_range_flag;
- return (PNG_INFO_cICP);
- }
-
- return 0;
-}
-#endif
-
-#ifdef PNG_cLLI_SUPPORTED
-# ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cLLI_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32p maxCLL,
- png_uint_32p maxFALL)
-{
- png_debug1(1, "in %s retrieval function", "cLLI");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cLLI) != 0)
- {
- if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL;
- if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL;
- return PNG_INFO_cLLI;
- }
-
- return 0;
-}
-# endif
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_cLLI(png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *maxCLL, double *maxFALL)
-{
- png_debug1(1, "in %s retrieval function", "cLLI(float)");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_cLLI) != 0)
- {
- if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL * .0001;
- if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL * .0001;
- return PNG_INFO_cLLI;
- }
-
- return 0;
-}
-# endif
-#endif /* cLLI */
-
-#ifdef PNG_mDCV_SUPPORTED
-# ifdef PNG_FIXED_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_mDCV_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_fixed_point *white_x, png_fixed_point *white_y,
- png_fixed_point *red_x, png_fixed_point *red_y,
- png_fixed_point *green_x, png_fixed_point *green_y,
- png_fixed_point *blue_x, png_fixed_point *blue_y,
- png_uint_32p mastering_maxDL, png_uint_32p mastering_minDL)
-{
- png_debug1(1, "in %s retrieval function", "mDCV");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_mDCV) != 0)
- {
- if (white_x != NULL) *white_x = info_ptr->mastering_white_x * 2;
- if (white_y != NULL) *white_y = info_ptr->mastering_white_y * 2;
- if (red_x != NULL) *red_x = info_ptr->mastering_red_x * 2;
- if (red_y != NULL) *red_y = info_ptr->mastering_red_y * 2;
- if (green_x != NULL) *green_x = info_ptr->mastering_green_x * 2;
- if (green_y != NULL) *green_y = info_ptr->mastering_green_y * 2;
- if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * 2;
- if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * 2;
- if (mastering_maxDL != NULL) *mastering_maxDL = info_ptr->mastering_maxDL;
- if (mastering_minDL != NULL) *mastering_minDL = info_ptr->mastering_minDL;
- return PNG_INFO_mDCV;
- }
-
- return 0;
-}
-# endif
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-png_uint_32 PNGAPI
-png_get_mDCV(png_const_structrp png_ptr, png_const_inforp info_ptr,
- double *white_x, double *white_y, double *red_x, double *red_y,
- double *green_x, double *green_y, double *blue_x, double *blue_y,
- double *mastering_maxDL, double *mastering_minDL)
-{
- png_debug1(1, "in %s retrieval function", "mDCV(float)");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_mDCV) != 0)
- {
- if (white_x != NULL) *white_x = info_ptr->mastering_white_x * .00002;
- if (white_y != NULL) *white_y = info_ptr->mastering_white_y * .00002;
- if (red_x != NULL) *red_x = info_ptr->mastering_red_x * .00002;
- if (red_y != NULL) *red_y = info_ptr->mastering_red_y * .00002;
- if (green_x != NULL) *green_x = info_ptr->mastering_green_x * .00002;
- if (green_y != NULL) *green_y = info_ptr->mastering_green_y * .00002;
- if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * .00002;
- if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * .00002;
- if (mastering_maxDL != NULL)
- *mastering_maxDL = info_ptr->mastering_maxDL * .0001;
- if (mastering_minDL != NULL)
- *mastering_minDL = info_ptr->mastering_minDL * .0001;
- return PNG_INFO_mDCV;
- }
-
- return 0;
-}
-# endif /* FLOATING_POINT */
-#endif /* mDCV */
-
-#ifdef PNG_eXIf_SUPPORTED
-png_uint_32 PNGAPI
-png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
- png_bytep *exif)
-{
- png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
- PNG_UNUSED(info_ptr)
- PNG_UNUSED(exif)
- return 0;
-}
-
-png_uint_32 PNGAPI
-png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
- png_uint_32 *num_exif, png_bytep *exif)
-{
- png_debug1(1, "in %s retrieval function", "eXIf");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
- {
- *num_exif = info_ptr->num_exif;
- *exif = info_ptr->exif;
- return PNG_INFO_eXIf;
- }
-
- return 0;
+ return (0);
}
#endif
@@ -923,14 +747,14 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "hIST");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+ && hist != NULL)
{
*hist = info_ptr->hist;
- return PNG_INFO_hIST;
+ return (PNG_INFO_hIST);
}
- return 0;
+ return (0);
}
#endif
@@ -942,20 +766,14 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "IHDR");
- if (png_ptr == NULL || info_ptr == NULL)
- return 0;
+ if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
+ height == NULL || bit_depth == NULL || color_type == NULL)
+ return (0);
- if (width != NULL)
- *width = info_ptr->width;
-
- if (height != NULL)
- *height = info_ptr->height;
-
- if (bit_depth != NULL)
- *bit_depth = info_ptr->bit_depth;
-
- if (color_type != NULL)
- *color_type = info_ptr->color_type;
+ *width = info_ptr->width;
+ *height = info_ptr->height;
+ *bit_depth = info_ptr->bit_depth;
+ *color_type = info_ptr->color_type;
if (compression_type != NULL)
*compression_type = info_ptr->compression_type;
@@ -975,7 +793,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
info_ptr->compression_type, info_ptr->filter_type);
- return 1;
+ return (1);
}
#ifdef PNG_oFFs_SUPPORTED
@@ -985,17 +803,16 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "oFFs");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
- offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+ && offset_x != NULL && offset_y != NULL && unit_type != NULL)
{
*offset_x = info_ptr->x_offset;
*offset_y = info_ptr->y_offset;
*unit_type = (int)info_ptr->offset_unit_type;
- return PNG_INFO_oFFs;
+ return (PNG_INFO_oFFs);
}
- return 0;
+ return (0);
}
#endif
@@ -1007,9 +824,8 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "pCAL");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
- purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+ && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
nparams != NULL && units != NULL && params != NULL)
{
*purpose = info_ptr->pcal_purpose;
@@ -1019,10 +835,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
*nparams = (int)info_ptr->pcal_nparams;
*units = info_ptr->pcal_units;
*params = info_ptr->pcal_params;
- return PNG_INFO_pCAL;
+ return (PNG_INFO_pCAL);
}
- return 0;
+ return (0);
}
#endif
@@ -1034,10 +850,8 @@ png_uint_32 PNGAPI
png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_fixed_point *width, png_fixed_point *height)
{
- png_debug1(1, "in %s retrieval function", "sCAL");
-
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ (info_ptr->valid & PNG_INFO_sCAL))
{
*unit = info_ptr->scal_unit;
/*TODO: make this work without FP support; the API is currently eliminated
@@ -1046,11 +860,11 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*/
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
- "sCAL height");
- return PNG_INFO_sCAL;
+ "sCAL height");
+ return (PNG_INFO_sCAL);
}
- return 0;
+ return(0);
}
# endif /* FLOATING_ARITHMETIC */
# endif /* FIXED_POINT */
@@ -1059,36 +873,32 @@ png_uint_32 PNGAPI
png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, double *width, double *height)
{
- png_debug1(1, "in %s retrieval function", "sCAL(float)");
-
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ (info_ptr->valid & PNG_INFO_sCAL))
{
*unit = info_ptr->scal_unit;
*width = atof(info_ptr->scal_s_width);
*height = atof(info_ptr->scal_s_height);
- return PNG_INFO_sCAL;
+ return (PNG_INFO_sCAL);
}
- return 0;
+ return(0);
}
# endif /* FLOATING POINT */
png_uint_32 PNGAPI
png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_charpp width, png_charpp height)
{
- png_debug1(1, "in %s retrieval function", "sCAL(str)");
-
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ (info_ptr->valid & PNG_INFO_sCAL))
{
*unit = info_ptr->scal_unit;
*width = info_ptr->scal_s_width;
*height = info_ptr->scal_s_height;
- return PNG_INFO_sCAL;
+ return (PNG_INFO_sCAL);
}
- return 0;
+ return(0);
}
#endif /* sCAL */
@@ -1102,7 +912,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "pHYs");
if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ (info_ptr->valid & PNG_INFO_pHYs))
{
if (res_x != NULL)
{
@@ -1123,7 +933,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
- return retval;
+ return (retval);
}
#endif /* pHYs */
@@ -1133,16 +943,16 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "PLTE");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+ && palette != NULL)
{
*palette = info_ptr->palette;
*num_palette = info_ptr->num_palette;
png_debug1(3, "num_palette = %d", *num_palette);
- return PNG_INFO_PLTE;
+ return (PNG_INFO_PLTE);
}
- return 0;
+ return (0);
}
#ifdef PNG_sBIT_SUPPORTED
@@ -1152,14 +962,14 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "sBIT");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+ && sig_bit != NULL)
{
*sig_bit = &(info_ptr->sig_bit);
- return PNG_INFO_sBIT;
+ return (PNG_INFO_sBIT);
}
- return 0;
+ return (0);
}
#endif
@@ -1170,7 +980,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
{
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
{
- png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx",
+ png_debug1(1, "in 0x%lx retrieval function",
(unsigned long)png_ptr->chunk_name);
if (text_ptr != NULL)
@@ -1185,7 +995,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
if (num_text != NULL)
*num_text = 0;
- return 0;
+ return(0);
}
#endif
@@ -1196,14 +1006,14 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_debug1(1, "in %s retrieval function", "tIME");
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+ && mod_time != NULL)
{
*mod_time = &(info_ptr->mod_time);
- return PNG_INFO_tIME;
+ return (PNG_INFO_tIME);
}
- return 0;
+ return (0);
}
#endif
@@ -1213,12 +1023,10 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
{
png_uint_32 retval = 0;
-
- png_debug1(1, "in %s retrieval function", "tRNS");
-
- if (png_ptr != NULL && info_ptr != NULL &&
- (info_ptr->valid & PNG_INFO_tRNS) != 0)
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
{
+ png_debug1(1, "in %s retrieval function", "tRNS");
+
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (trans_alpha != NULL)
@@ -1250,7 +1058,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
}
}
- return retval;
+ return (retval);
}
#endif
@@ -1265,13 +1073,13 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
return info_ptr->unknown_chunks_num;
}
- return 0;
+ return (0);
}
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte PNGAPI
-png_get_rgb_to_gray_status(png_const_structrp png_ptr)
+png_get_rgb_to_gray_status (png_const_structrp png_ptr)
{
return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
}
@@ -1285,73 +1093,73 @@ png_get_user_chunk_ptr(png_const_structrp png_ptr)
}
#endif
-size_t PNGAPI
+png_size_t PNGAPI
png_get_compression_buffer_size(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
return 0;
-#ifdef PNG_WRITE_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
-#endif
+# ifdef PNG_WRITE_SUPPORTED
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+# endif
{
-#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
- return png_ptr->IDAT_read_size;
-#else
- return PNG_IDAT_READ_SIZE;
-#endif
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ return png_ptr->IDAT_read_size;
+# else
+ return PNG_IDAT_READ_SIZE;
+# endif
}
-#ifdef PNG_WRITE_SUPPORTED
- else
- return png_ptr->zbuffer_size;
-#endif
+# ifdef PNG_WRITE_SUPPORTED
+ else
+ return png_ptr->zbuffer_size;
+# endif
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* These functions were added to libpng 1.2.6 and were enabled
* by default in libpng-1.4.0 */
png_uint_32 PNGAPI
-png_get_user_width_max(png_const_structrp png_ptr)
+png_get_user_width_max (png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->user_width_max : 0);
}
png_uint_32 PNGAPI
-png_get_user_height_max(png_const_structrp png_ptr)
+png_get_user_height_max (png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->user_height_max : 0);
}
/* This function was added to libpng 1.4.0 */
png_uint_32 PNGAPI
-png_get_chunk_cache_max(png_const_structrp png_ptr)
+png_get_chunk_cache_max (png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
}
/* This function was added to libpng 1.4.1 */
png_alloc_size_t PNGAPI
-png_get_chunk_malloc_max(png_const_structrp png_ptr)
+png_get_chunk_malloc_max (png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
}
-#endif /* SET_USER_LIMITS */
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
/* These functions were added to libpng 1.4.0 */
#ifdef PNG_IO_STATE_SUPPORTED
png_uint_32 PNGAPI
-png_get_io_state(png_const_structrp png_ptr)
+png_get_io_state (png_const_structrp png_ptr)
{
return png_ptr->io_state;
}
png_uint_32 PNGAPI
-png_get_io_chunk_type(png_const_structrp png_ptr)
+png_get_io_chunk_type (png_const_structrp png_ptr)
{
return png_ptr->chunk_name;
}
-#endif /* IO_STATE */
+#endif /* ?PNG_IO_STATE_SUPPORTED */
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
@@ -1361,9 +1169,9 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return png_ptr->num_palette_max;
- return -1;
+ return (-1);
}
# endif
#endif
-#endif /* READ || WRITE */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pnginfo.h b/Windows_Libs/Dev/Render/libpng/pnginfo.h
index 584a42f..26bf265 100644
--- a/Windows_Libs/Dev/Render/libpng/pnginfo.h
+++ b/Windows_Libs/Dev/Render/libpng/pnginfo.h
@@ -1,29 +1,54 @@
-/* pnginfo.h - internal structures for libpng
+
+/* pnginfo.h - header file for PNG reference library
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
-#ifndef PNGPRIV_H
-# error This file must not be included by applications; please include
-#endif
-
-/* INTERNAL, PRIVATE definition of a PNG.
+ /* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, using png_set_*() functions, then
+ * call png_write_info().
*
- * png_info is a modifiable description of a PNG datastream. The fields inside
- * this structure are accessed through png_get_() functions and modified
- * using png_set_() functions.
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
*
- * Some functions in libpng do directly access members of png_info. However,
- * this should be avoided. png_struct objects contain members which hold
- * caches, sometimes optimised, of the values from png_info objects, and
- * png_info is not passed to the functions which read and write image data.
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality. In libpng-1.5.0 this was moved into a separate private
+ * file that is not visible to applications.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
*/
#ifndef PNGINFO_H
#define PNGINFO_H
@@ -31,10 +56,10 @@
struct png_info_def
{
/* The following are necessary for every PNG file */
- png_uint_32 width; /* width of image in pixels (from IHDR) */
- png_uint_32 height; /* height of image in pixels (from IHDR) */
- png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
- size_t rowbytes; /* bytes needed to hold an untransformed row */
+ png_uint_32 width; /* width of image in pixels (from IHDR) */
+ png_uint_32 height; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
+ png_size_t rowbytes; /* bytes needed to hold an untransformed row */
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
@@ -63,12 +88,18 @@ struct png_info_def
* and initialize the appropriate fields below.
*/
-#ifdef PNG_cICP_SUPPORTED
- /* cICP chunk data */
- png_byte cicp_colour_primaries;
- png_byte cicp_transfer_function;
- png_byte cicp_matrix_coefficients;
- png_byte cicp_video_full_range_flag;
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
+ * defined. When COLORSPACE is switched on all the colorspace-defining
+ * chunks should be enabled, when GAMMA is switched on all the gamma-defining
+ * chunks should be enabled. If this is not done it becomes possible to read
+ * inconsistent PNG files and assign a probably incorrect interpretation to
+ * the information. (In other words, by carefully choosing which chunks to
+ * recognize the system configuration can select an interpretation for PNG
+ * files containing ambiguous data and this will result in inconsistent
+ * behavior between different libpng builds!)
+ */
+ png_colorspace colorspace;
#endif
#ifdef PNG_iCCP_SUPPORTED
@@ -78,24 +109,6 @@ struct png_info_def
png_uint_32 iccp_proflen; /* ICC profile data length */
#endif
-#ifdef PNG_cLLI_SUPPORTED
- png_uint_32 maxCLL; /* cd/m2 (nits) * 10,000 */
- png_uint_32 maxFALL;
-#endif
-
-#ifdef PNG_mDCV_SUPPORTED
- png_uint_16 mastering_red_x; /* CIE (xy) x * 50,000 */
- png_uint_16 mastering_red_y;
- png_uint_16 mastering_green_x;
- png_uint_16 mastering_green_y;
- png_uint_16 mastering_blue_x;
- png_uint_16 mastering_blue_y;
- png_uint_16 mastering_white_x;
- png_uint_16 mastering_white_y;
- png_uint_32 mastering_maxDL; /* cd/m2 (nits) * 10,000 */
- png_uint_32 mastering_minDL;
-#endif
-
#ifdef PNG_TEXT_SUPPORTED
/* The tEXt, and zTXt chunks contain human-readable textual data in
* uncompressed, compressed, and optionally compressed forms, respectively.
@@ -108,7 +121,7 @@ struct png_info_def
int num_text; /* number of comments read or comments to write */
int max_text; /* current size of text array */
png_textp text; /* array of comments read or comments to write */
-#endif /* TEXT */
+#endif /* PNG_TEXT_SUPPORTED */
#ifdef PNG_tIME_SUPPORTED
/* The tIME chunk holds the last time the displayed image data was
@@ -173,11 +186,6 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif
-#ifdef PNG_eXIf_SUPPORTED
- png_uint_32 num_exif; /* Added at libpng-1.6.31 */
- png_bytep exif;
-#endif
-
#ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a
@@ -216,7 +224,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks;
- /* The type of this field is limited by the type of
+ /* The type of this field is limited by the type of
* png_struct::user_chunk_cache_max, else overflow can occur.
*/
int unknown_chunks_num;
@@ -232,7 +240,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The sCAL chunk describes the actual physical dimensions of the
* subject matter of the graphic. The chunk contains a unit specification
* a byte value, and two ASCII strings representing floating-point
- * values. The values are width and height corresponding to one pixel
+ * values. The values are width and height corresponsing to one pixel
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
* non-zero.
*/
@@ -248,16 +256,5 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytepp row_pointers; /* the image bits */
#endif
-#ifdef PNG_cHRM_SUPPORTED
- png_xy cHRM;
-#endif
-
-#ifdef PNG_gAMA_SUPPORTED
- png_fixed_point gamma;
-#endif
-
-#ifdef PNG_sRGB_SUPPORTED
- int rendering_intent;
-#endif
};
#endif /* PNGINFO_H */
diff --git a/Windows_Libs/Dev/Render/libpng/pnglibconf.h b/Windows_Libs/Dev/Render/libpng/pnglibconf.h
index e12c895..d616b57 100644
--- a/Windows_Libs/Dev/Render/libpng/pnglibconf.h
+++ b/Windows_Libs/Dev/Render/libpng/pnglibconf.h
@@ -1,9 +1,10 @@
+/* libpng 1.6.2 STANDARD API DEFINITION */
+
/* pnglibconf.h - library build configuration */
-/* libpng version 1.6.55 */
+/* Libpng version 1.6.2 - April 25, 2013 */
-/* Copyright (c) 2018-2026 Cosmin Truta */
-/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
+/* Copyright (c) 1998-2013 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
@@ -19,6 +20,7 @@
#define PNG_ALIGNED_MEMORY_SUPPORTED
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
+/*#undef PNG_ARM_NEON_SUPPORTED*/
#define PNG_BENIGN_ERRORS_SUPPORTED
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
@@ -27,7 +29,6 @@
#define PNG_COLORSPACE_SUPPORTED
//#define PNG_CONSOLE_IO_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
-/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/
#define PNG_EASY_ACCESS_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_ERROR_TEXT_SUPPORTED
@@ -42,14 +43,8 @@
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
-/*#undef PNG_MIPS_MMI_API_SUPPORTED*/
-/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/
-/*#undef PNG_MIPS_MSA_API_SUPPORTED*/
-/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
-/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
-/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_ALPHA_MODE_SUPPORTED
@@ -88,14 +83,10 @@
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
-#define PNG_READ_cICP_SUPPORTED
-#define PNG_READ_cLLI_SUPPORTED
-#define PNG_READ_eXIf_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED
-#define PNG_READ_mDCV_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
@@ -107,11 +98,14 @@
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
+/*#undef PNG_SAFE_LIMITS_SUPPORTED*/
#define PNG_SAVE_INT_32_SUPPORTED
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_SETJMP_SUPPORTED
-#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
+#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+/*#undef PNG_SET_OPTION_SUPPORTED*/
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
@@ -119,7 +113,6 @@
#define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
-#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
@@ -137,7 +130,6 @@
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
-#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED
@@ -161,14 +153,10 @@
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
-#define PNG_WRITE_cICP_SUPPORTED
-#define PNG_WRITE_cLLI_SUPPORTED
-#define PNG_WRITE_eXIf_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED
-#define PNG_WRITE_mDCV_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
@@ -182,14 +170,10 @@
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_cHRM_SUPPORTED
-#define PNG_cICP_SUPPORTED
-#define PNG_cLLI_SUPPORTED
-#define PNG_eXIf_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
#define PNG_iTXt_SUPPORTED
-#define PNG_mDCV_SUPPORTED
#define PNG_oFFs_SUPPORTED
#define PNG_pCAL_SUPPORTED
#define PNG_pHYs_SUPPORTED
@@ -204,30 +188,24 @@
/* end of options */
/* settings */
#define PNG_API_RULE 0
+#define PNG_CALLOC_SUPPORTED
+#define PNG_COST_SHIFT 3
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
#define PNG_INFLATE_BUF_SIZE 1024
-#define PNG_LINKAGE_API extern
-#define PNG_LINKAGE_CALLBACK extern
-#define PNG_LINKAGE_DATA extern
-#define PNG_LINKAGE_FUNCTION extern
#define PNG_MAX_GAMMA_8 11
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_QUANTIZE_RED_BITS 5
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
-#define PNG_USER_CHUNK_CACHE_MAX 1000
-#define PNG_USER_CHUNK_MALLOC_MAX 8000000
-#define PNG_USER_HEIGHT_MAX 1000000
-#define PNG_USER_WIDTH_MAX 1000000
+#define PNG_WEIGHT_SHIFT 8
#define PNG_ZBUF_SIZE 8192
-#define PNG_ZLIB_VERNUM 0 /* unknown */
#define PNG_Z_DEFAULT_COMPRESSION (-1)
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
#define PNG_Z_DEFAULT_STRATEGY 1
#define PNG_sCAL_PRECISION 5
#define PNG_sRGB_PROFILE_CHECKS 2
/* end of settings */
-#endif /* PNGLCONF_H */
+#endif /* PNGLCONF_H */
\ No newline at end of file
diff --git a/Windows_Libs/Dev/Render/libpng/pngmem.c b/Windows_Libs/Dev/Render/libpng/pngmem.c
index b7adff8..b9b3efb 100644
--- a/Windows_Libs/Dev/Render/libpng/pngmem.c
+++ b/Windows_Libs/Dev/Render/libpng/pngmem.c
@@ -1,9 +1,10 @@
+
/* pngmem.c - stub functions for memory allocation
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -40,14 +41,13 @@ png_destroy_png_struct(png_structrp png_ptr)
}
/* Allocate memory. For reasonable files, size should never exceed
- * 64K. However, zlib may allocate more than 64K if you don't tell
+ * 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*/
PNG_FUNCTION(png_voidp,PNGAPI
-png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
@@ -66,49 +66,44 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),
*/
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+ PNG_ALLOCATED)
{
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
* allocators have also been removed in 1.6.0, so any 16-bit system now has
* to implement a user memory handler. This checks to be sure it isn't
* called with big numbers.
*/
-# ifdef PNG_MAX_MALLOC_64K
- /* This is support for legacy systems which had segmented addressing
- * limiting the maximum allocation size to 65536. It takes precedence
- * over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems.
- *
- * TODO: libpng-1.8: finally remove both cases.
- */
- if (size > 65536U) return NULL;
-# endif
-
- /* This is checked too because the system malloc call below takes a (size_t).
- */
- if (size > PNG_SIZE_MAX) return NULL;
-
-# ifdef PNG_USER_MEM_SUPPORTED
+#ifdef PNG_USER_MEM_SUPPORTED
+ PNG_UNUSED(png_ptr)
+#endif
+ if (size > 0 && size <= PNG_SIZE_MAX
+# ifdef PNG_MAX_MALLOC_64K
+ && size <= 65536U
+# endif
+ )
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
-# else
- PNG_UNUSED(png_ptr)
-# endif
- /* Use the system malloc */
- return malloc((size_t)/*SAFE*/size); /* checked for truncation above */
+ else
+#endif
+ return malloc((size_t)size); /* checked for truncation above */
+ }
+
+ else
+ return NULL;
}
-#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
- defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
* that arises because of the checks in png_realloc_array that are repeated in
* png_malloc_array.
*/
static png_voidp
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
- size_t element_size)
+ size_t element_size)
{
- png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
+ png_alloc_size_t req = nelements; /* known to be > 0 */
if (req <= PNG_SIZE_MAX/element_size)
return png_malloc_base(png_ptr, req * element_size);
@@ -119,8 +114,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_array,(png_const_structrp png_ptr, int nelements,
- size_t element_size),
- PNG_ALLOCATED)
+ size_t element_size),PNG_ALLOCATED)
{
if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc");
@@ -130,8 +124,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
- int old_elements, int add_elements, size_t element_size),
- PNG_ALLOCATED)
+ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
{
/* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
@@ -144,7 +137,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
if (add_elements <= INT_MAX - old_elements)
{
png_voidp new_array = png_malloc_array_checked(png_ptr,
- old_elements+add_elements, element_size);
+ old_elements+add_elements, element_size);
if (new_array != NULL)
{
@@ -155,7 +148,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
- element_size*(unsigned)add_elements);
+ element_size*(unsigned)add_elements);
return new_array;
}
@@ -163,15 +156,13 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
return NULL; /* error */
}
-#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
/* Various functions that have different error handling are derived from this.
* png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
* function png_malloc_default is also provided.
*/
PNG_FUNCTION(png_voidp,PNGAPI
-png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
{
png_voidp ret;
@@ -189,7 +180,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),
#ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED PNG_DEPRECATED)
+ PNG_ALLOCATED PNG_DEPRECATED)
{
png_voidp ret;
@@ -204,7 +195,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
return ret;
}
-#endif /* USER_MEM */
+#endif /* PNG_USER_MEM_SUPPORTED */
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
* function will issue a png_warning and return NULL instead of issuing a
@@ -212,7 +203,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED)
+ PNG_ALLOCATED)
{
if (png_ptr != NULL)
{
@@ -245,12 +236,11 @@ png_free(png_const_structrp png_ptr, png_voidp ptr)
}
PNG_FUNCTION(void,PNGAPI
-png_free_default,(png_const_structrp png_ptr, png_voidp ptr),
- PNG_DEPRECATED)
+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
{
if (png_ptr == NULL || ptr == NULL)
return;
-#endif /* USER_MEM */
+#endif /* PNG_USER_MEM_SUPPORTED */
free(ptr);
}
@@ -260,8 +250,8 @@ png_free_default,(png_const_structrp png_ptr, png_voidp ptr),
* of allocating and freeing memory.
*/
void PNGAPI
-png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
{
if (png_ptr != NULL)
{
@@ -283,5 +273,5 @@ png_get_mem_ptr(png_const_structrp png_ptr)
return png_ptr->mem_ptr;
}
-#endif /* USER_MEM */
-#endif /* READ || WRITE */
+#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngpread.c b/Windows_Libs/Dev/Render/libpng/pngpread.c
index 37aa432..f132ce6 100644
--- a/Windows_Libs/Dev/Render/libpng/pngpread.c
+++ b/Windows_Libs/Dev/Render/libpng/pngpread.c
@@ -1,9 +1,10 @@
+
/* pngpread.c - read a png file in push mode
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -18,37 +19,16 @@
#define PNG_READ_SIG_MODE 0
#define PNG_READ_CHUNK_MODE 1
#define PNG_READ_IDAT_MODE 2
+#define PNG_SKIP_MODE 3
#define PNG_READ_tEXt_MODE 4
#define PNG_READ_zTXt_MODE 5
#define PNG_READ_DONE_MODE 6
#define PNG_READ_iTXt_MODE 7
#define PNG_ERROR_MODE 8
-#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
-if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
- { png_push_save_buffer(png_ptr); return; }
-#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
-if (png_ptr->buffer_size < N) \
- { png_push_save_buffer(png_ptr); return; }
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
-
-/* Start of interlace block */
-static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-/* Offset to next interlace block */
-static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-/* Start of interlace block in the y direction */
-static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-/* Offset to next interlace block in the y direction */
-static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-
-/* TODO: Move these arrays to a common utility module to avoid duplication. */
-#endif
-
void PNGAPI
png_process_data(png_structrp png_ptr, png_inforp info_ptr,
- png_bytep buffer, size_t buffer_size)
+ png_bytep buffer, png_size_t buffer_size)
{
if (png_ptr == NULL || info_ptr == NULL)
return;
@@ -61,20 +41,20 @@ png_process_data(png_structrp png_ptr, png_inforp info_ptr,
}
}
-size_t PNGAPI
+png_size_t PNGAPI
png_process_data_pause(png_structrp png_ptr, int save)
{
if (png_ptr != NULL)
{
- /* It's easiest for the caller if we do the save; then the caller doesn't
+ /* It's easiest for the caller if we do the save, then the caller doesn't
* have to supply the same data again:
*/
- if (save != 0)
+ if (save)
png_push_save_buffer(png_ptr);
else
{
/* This includes any pending saved bytes: */
- size_t remaining = png_ptr->buffer_size;
+ png_size_t remaining = png_ptr->buffer_size;
png_ptr->buffer_size = 0;
/* So subtract the saved buffer size, unless all the data
@@ -91,14 +71,32 @@ png_process_data_pause(png_structrp png_ptr, int save)
png_uint_32 PNGAPI
png_process_data_skip(png_structrp png_ptr)
{
-/* TODO: Deprecate and remove this API.
- * Somewhere the implementation of this seems to have been lost,
- * or abandoned. It was only to support some internal back-door access
- * to png_struct) in libpng-1.4.x.
- */
- png_app_warning(png_ptr,
-"png_process_data_skip is not implemented in any current version of libpng");
- return 0;
+ png_uint_32 remaining = 0;
+
+ if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
+ png_ptr->skip_length > 0)
+ {
+ /* At the end of png_process_data the buffer size must be 0 (see the loop
+ * above) so we can detect a broken call here:
+ */
+ if (png_ptr->buffer_size != 0)
+ png_error(png_ptr,
+ "png_process_data_skip called inside png_process_data");
+
+ /* If is impossible for there to be a saved buffer at this point -
+ * otherwise we could not be in SKIP mode. This will also happen if
+ * png_process_skip is called inside png_process_data (but only very
+ * rarely.)
+ */
+ if (png_ptr->save_buffer_size != 0)
+ png_error(png_ptr, "png_process_data_skip called with saved data");
+
+ remaining = png_ptr->skip_length;
+ png_ptr->skip_length = 0;
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+
+ return remaining;
}
/* What we do with the incoming data depends on what we were previously
@@ -130,6 +128,12 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
break;
}
+ case PNG_SKIP_MODE:
+ {
+ png_push_crc_finish(png_ptr);
+ break;
+ }
+
default:
{
png_ptr->buffer_size = 0;
@@ -147,8 +151,8 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{
- size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
- size_t num_to_check = 8 - num_checked;
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check)
{
@@ -159,10 +163,10 @@ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
num_to_check);
png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
{
if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
png_error(png_ptr, "Not a PNG file");
else
@@ -185,16 +189,29 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
int keep; /* unknown handling method */
#endif
- /* First we make sure we have enough data for the 4-byte chunk name
- * and the 4-byte chunk length before proceeding with decoding the
+ /* First we make sure we have enough data for the 4 byte chunk name
+ * and the 4 byte chunk length before proceeding with decoding the
* chunk data. To fully decode each of these chunks, we also make
- * sure we have enough data in the buffer for the 4-byte CRC at the
+ * sure we have enough data in the buffer for the 4 byte CRC at the
* end of every chunk (except IDAT, which is handled separately).
*/
- if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{
- PNG_PUSH_SAVE_BUFFER_IF_LT(8)
- png_ptr->push_length = png_read_chunk_header(png_ptr);
+ png_byte chunk_length[4];
+ png_byte chunk_tag[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, chunk_tag, 4);
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
}
@@ -202,39 +219,28 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
if (chunk_name == png_IDAT)
{
- if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+ if (png_ptr->mode & PNG_AFTER_IDAT)
png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
/* If we reach an IDAT chunk, this means we have read all of the
* header chunks, and we can start reading the image (or if this
* is called after the image has been read - we have an error).
*/
- if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT");
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ !(png_ptr->mode & PNG_HAVE_PLTE))
png_error(png_ptr, "Missing PLTE before IDAT");
- png_ptr->process_mode = PNG_READ_IDAT_MODE;
-
- if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
- if (png_ptr->push_length == 0)
- return;
-
png_ptr->mode |= PNG_HAVE_IDAT;
- if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
- png_benign_error(png_ptr, "Too many IDATs found");
- }
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ if (png_ptr->push_length == 0)
+ return;
- else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- {
- /* These flags must be set consistently for all non-IDAT chunks,
- * including the unknown chunks.
- */
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT;
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_benign_error(png_ptr, "Too many IDATs found");
}
if (chunk_name == png_IHDR)
@@ -242,14 +248,24 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
if (png_ptr->push_length != 13)
png_error(png_ptr, "Invalid IHDR length");
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
}
else if (chunk_name == png_IEND)
{
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
png_ptr->process_mode = PNG_READ_DONE_MODE;
png_push_have_end(png_ptr, info_ptr);
@@ -258,13 +274,28 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
{
- PNG_PUSH_SAVE_BUFFER_IF_FULL
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
if (chunk_name == png_PLTE)
png_ptr->mode |= PNG_HAVE_PLTE;
}
+
#endif
+ else if (chunk_name == png_PLTE)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
else if (chunk_name == png_IDAT)
{
@@ -278,17 +309,311 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
return;
}
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (png_ptr->chunk_name == png_gAMA)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (png_ptr->chunk_name == png_sBIT)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (png_ptr->chunk_name == png_cHRM)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (png_ptr->chunk_name == png_iCCP)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
else
{
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
}
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
}
+void /* PRIVATE */
+png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip)
+{
+ png_ptr->process_mode = PNG_SKIP_MODE;
+ png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structrp png_ptr)
+{
+ if (png_ptr->skip_length && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size = png_ptr->save_buffer_size;
+ png_uint_32 skip_length = png_ptr->skip_length;
+
+ /* We want the smaller of 'skip_length' and 'save_buffer_size', but
+ * they are of different types and we don't know which variable has the
+ * fewest bits. Carefully select the smaller and cast it to the type of
+ * the larger - this cannot overflow. Do not cast in the following test
+ * - it will break on either 16 or 64 bit platforms.
+ */
+ if (skip_length < save_size)
+ save_size = (png_size_t)skip_length;
+
+ else
+ skip_length = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= skip_length;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->skip_length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size = png_ptr->current_buffer_size;
+ png_uint_32 skip_length = png_ptr->skip_length;
+
+ /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
+ * the same problem exists as above and the same solution.
+ */
+ if (skip_length < save_size)
+ save_size = (png_size_t)skip_length;
+
+ else
+ skip_length = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= skip_length;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->skip_length)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+}
+
void PNGCBAPI
-png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
{
png_bytep ptr;
@@ -296,9 +621,9 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
return;
ptr = buffer;
- if (png_ptr->save_buffer_size != 0)
+ if (png_ptr->save_buffer_size)
{
- size_t save_size;
+ png_size_t save_size;
if (length < png_ptr->save_buffer_size)
save_size = length;
@@ -313,9 +638,9 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += save_size;
}
- if (length != 0 && png_ptr->current_buffer_size != 0)
+ if (length && png_ptr->current_buffer_size)
{
- size_t save_size;
+ png_size_t save_size;
if (length < png_ptr->current_buffer_size)
save_size = length;
@@ -333,11 +658,11 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
void /* PRIVATE */
png_push_save_buffer(png_structrp png_ptr)
{
- if (png_ptr->save_buffer_size != 0)
+ if (png_ptr->save_buffer_size)
{
if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
{
- size_t i, istop;
+ png_size_t i, istop;
png_bytep sp;
png_bytep dp;
@@ -352,7 +677,7 @@ png_push_save_buffer(png_structrp png_ptr)
if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
png_ptr->save_buffer_max)
{
- size_t new_max;
+ png_size_t new_max;
png_bytep old_buffer;
if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
@@ -364,7 +689,7 @@ png_push_save_buffer(png_structrp png_ptr)
new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
old_buffer = png_ptr->save_buffer;
png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
- (size_t)new_max);
+ (png_size_t)new_max);
if (png_ptr->save_buffer == NULL)
{
@@ -372,10 +697,7 @@ png_push_save_buffer(png_structrp png_ptr)
png_error(png_ptr, "Insufficient memory for save_buffer");
}
- if (old_buffer)
- memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
- else if (png_ptr->save_buffer_size)
- png_error(png_ptr, "save_buffer error");
+ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max;
}
@@ -392,7 +714,7 @@ png_push_save_buffer(png_structrp png_ptr)
void /* PRIVATE */
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
- size_t buffer_length)
+ png_size_t buffer_length)
{
png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length;
@@ -403,13 +725,18 @@ png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
void /* PRIVATE */
png_push_read_IDAT(png_structrp png_ptr)
{
- if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{
png_byte chunk_length[4];
png_byte chunk_tag[4];
/* TODO: this code can be commoned up with the same code in push_read */
- PNG_PUSH_SAVE_BUFFER_IF_LT(8)
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
png_reset_crc(png_ptr);
@@ -421,7 +748,7 @@ png_push_read_IDAT(png_structrp png_ptr)
{
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
png_error(png_ptr, "Not enough compressed data");
return;
@@ -430,19 +757,19 @@ png_push_read_IDAT(png_structrp png_ptr)
png_ptr->idat_size = png_ptr->push_length;
}
- if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
+ if (png_ptr->idat_size && png_ptr->save_buffer_size)
{
- size_t save_size = png_ptr->save_buffer_size;
+ png_size_t save_size = png_ptr->save_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size;
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they
* are of different types and we don't know which variable has the fewest
* bits. Carefully select the smaller and cast it to the type of the
* larger - this cannot overflow. Do not cast in the following test - it
- * will break on either 16-bit or 64-bit platforms.
+ * will break on either 16 or 64 bit platforms.
*/
if (idat_size < save_size)
- save_size = (size_t)idat_size;
+ save_size = (png_size_t)idat_size;
else
idat_size = (png_uint_32)save_size;
@@ -457,9 +784,9 @@ png_push_read_IDAT(png_structrp png_ptr)
png_ptr->save_buffer_ptr += save_size;
}
- if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
+ if (png_ptr->idat_size && png_ptr->current_buffer_size)
{
- size_t save_size = png_ptr->current_buffer_size;
+ png_size_t save_size = png_ptr->current_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size;
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they
@@ -468,7 +795,7 @@ png_push_read_IDAT(png_structrp png_ptr)
* larger - this cannot overflow.
*/
if (idat_size < save_size)
- save_size = (size_t)idat_size;
+ save_size = (png_size_t)idat_size;
else
idat_size = (png_uint_32)save_size;
@@ -482,10 +809,14 @@ png_push_read_IDAT(png_structrp png_ptr)
png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += save_size;
}
-
- if (png_ptr->idat_size == 0)
+ if (!png_ptr->idat_size)
{
- PNG_PUSH_SAVE_BUFFER_IF_LT(4)
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
png_crc_finish(png_ptr, 0);
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
png_ptr->mode |= PNG_AFTER_IDAT;
@@ -495,7 +826,7 @@ png_push_read_IDAT(png_structrp png_ptr)
void /* PRIVATE */
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
- size_t buffer_length)
+ png_size_t buffer_length)
{
/* The caller checks for a non-zero buffer length. */
if (!(buffer_length > 0) || buffer == NULL)
@@ -513,7 +844,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
* or the stream marked as finished.
*/
while (png_ptr->zstream.avail_in > 0 &&
- (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
{
int ret;
@@ -538,7 +869,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
* change the current behavior (see comments in inflate.c
* for why this doesn't happen at present with zlib 1.2.5).
*/
- ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
+ ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
/* Check for any failure before proceeding. */
if (ret != Z_OK && ret != Z_STREAM_END)
@@ -555,12 +886,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_warning(png_ptr, "Truncated compressed data in IDAT");
else
- {
- if (ret == Z_DATA_ERROR)
- png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
- else
- png_error(png_ptr, "Decompression error in IDAT");
- }
+ png_error(png_ptr, "Decompression error in IDAT");
/* Skip the check on unprocessed input */
return;
@@ -635,7 +961,7 @@ png_push_process_row(png_structrp png_ptr)
memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
- if (png_ptr->transformations != 0)
+ if (png_ptr->transformations)
png_do_read_transformations(png_ptr, &row_info);
#endif
@@ -652,16 +978,15 @@ png_push_process_row(png_structrp png_ptr)
#ifdef PNG_READ_INTERLACING_SUPPORTED
- /* Expand interlaced rows to full size */
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0)
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{
if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
- png_ptr->transformations);
+ png_ptr->transformations);
- switch (png_ptr->pass)
- {
+ switch (png_ptr->pass)
+ {
case 0:
{
int i;
@@ -838,12 +1163,33 @@ png_push_process_row(png_structrp png_ptr)
void /* PRIVATE */
png_read_push_finish_row(png_structrp png_ptr)
{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
png_ptr->row_number++;
if (png_ptr->row_number < png_ptr->num_rows)
return;
#ifdef PNG_READ_INTERLACING_SUPPORTED
- if (png_ptr->interlaced != 0)
+ if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
@@ -867,7 +1213,7 @@ png_read_push_finish_row(png_structrp png_ptr)
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
- if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ if (png_ptr->transformations & PNG_INTERLACE)
break;
png_ptr->num_rows = (png_ptr->height +
@@ -877,7 +1223,7 @@ png_read_push_finish_row(png_structrp png_ptr)
} while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
}
-#endif /* READ_INTERLACING */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
}
void /* PRIVATE */
@@ -899,7 +1245,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row)
{
if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
- (int)png_ptr->pass);
+ (int)png_ptr->pass);
}
#ifdef PNG_READ_INTERLACING_SUPPORTED
@@ -915,9 +1261,9 @@ png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
* it must be png_ptr->row_buf+1
*/
if (new_row != NULL)
- png_combine_row(png_ptr, old_row, 1/*blocky display*/);
+ png_combine_row(png_ptr, old_row, 1/*display*/);
}
-#endif /* READ_INTERLACING */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
void PNGAPI
png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
@@ -938,8 +1284,8 @@ png_voidp PNGAPI
png_get_progressive_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return NULL;
+ return (NULL);
return png_ptr->io_ptr;
}
-#endif /* PROGRESSIVE_READ */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngpriv.h b/Windows_Libs/Dev/Render/libpng/pngpriv.h
index f91666c..d06284d 100644
--- a/Windows_Libs/Dev/Render/libpng/pngpriv.h
+++ b/Windows_Libs/Dev/Render/libpng/pngpriv.h
@@ -1,9 +1,12 @@
+
/* pngpriv.h - private declarations for use inside libpng
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -19,20 +22,8 @@
* they should be well aware of the issues that may arise from doing so.
*/
-
-/* pngpriv.h must be included first in each translation unit inside libpng.
- * On the other hand, it must not be included at all, directly or indirectly,
- * by any application code that uses the libpng API.
- */
#ifndef PNGPRIV_H
-# define PNGPRIV_H
-#else
-# error Duplicate inclusion of pngpriv.h; please check the libpng source files
-#endif
-
-#if defined(PNG_H) || defined(PNGCONF_H) || defined(PNGLCONF_H)
-# error This file must not be included by applications; please include
-#endif
+#define PNGPRIV_H
/* Feature Test Macros. The following are defined here to ensure that correctly
* implemented libraries reveal the APIs libpng needs to build and hide those
@@ -46,9 +37,7 @@
* Windows/Visual Studio) there is no effect; the OS specific tests below are
* still required (as of 2011-05-02.)
*/
-#ifndef _POSIX_SOURCE
-# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
-#endif
+#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#ifndef PNG_VERSION_INFO_ONLY
/* Standard library headers not required by png.h: */
@@ -69,6 +58,7 @@
*/
#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
# include
+
/* Pick up the definition of 'restrict' from config.h if it was read: */
# define PNG_RESTRICT restrict
#endif
@@ -78,7 +68,9 @@
* are not internal definitions may be required. This is handled below just
* before png.h is included, but load the configuration now if it is available.
*/
-#include "pnglibconf.h"
+#ifndef PNGLCONF_H
+# include "pnglibconf.h"
+#endif
/* Local renames may change non-exported API functions from png.h */
#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)
@@ -96,222 +88,6 @@
# endif
#endif
-/* Compile time options.
- * =====================
- * In a multi-arch build the compiler may compile the code several times for the
- * same object module, producing different binaries for different architectures.
- * When this happens configure-time setting of the target host options cannot be
- * done and this interferes with the handling of the ARM NEON optimizations, and
- * possibly other similar optimizations. Put additional tests here; in general
- * this is needed when the same option can be changed at both compile time and
- * run time depending on the target OS (i.e. iOS vs Android.)
- *
- * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
- * this is not possible with certain compilers (Oracle SUN OS CC), as a result
- * it is necessary to ensure that all extern functions that *might* be used
- * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__
- * below is one example of this behavior because it is controlled by the
- * presence or not of -mfpu=neon on the GCC command line, it is possible to do
- * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
- * do this.
- */
-#ifndef PNG_ARM_NEON_OPT
- /* ARM NEON optimizations are being controlled by the compiler settings,
- * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon
- * with GCC) then the compiler will define __ARM_NEON__ and we can rely
- * unconditionally on NEON instructions not crashing, otherwise we must
- * disable use of NEON instructions.
- *
- * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they
- * can only be turned on automatically if that is supported too. If
- * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail
- * to compile with an appropriate #error if ALIGNED_MEMORY has been turned
- * off.
- *
- * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated
- * __ARM_NEON__, so we check both variants.
- *
- * To disable ARM_NEON optimizations entirely, and skip compiling the
- * associated assembler code, pass --enable-arm-neon=no to configure
- * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS.
- */
-# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
- defined(PNG_ALIGNED_MEMORY_SUPPORTED)
-# define PNG_ARM_NEON_OPT 2
-# else
-# define PNG_ARM_NEON_OPT 0
-# endif
-#endif
-
-#ifndef PNG_RISCV_RVV_OPT
- /* RISCV_RVV optimizations are being controlled by the compiler settings,
- * typically the target compiler will define __riscv but the rvv extension
- * availability has to be explicitly stated. This is why if no
- * PNG_RISCV_RVV_OPT was defined then a runtime check will be executed.
- *
- * To enable RISCV_RVV optimizations unconditionally, and compile the
- * associated code, pass --enable-riscv-rvv=yes or --enable-riscv-rvv=on
- * to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS.
- */
-
-# define PNG_RISCV_RVV_OPT 0
-#endif
-
-#if PNG_ARM_NEON_OPT > 0
- /* NEON optimizations are to be at least considered by libpng, so enable the
- * callbacks to do this.
- */
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
-# ifndef PNG_ARM_NEON_IMPLEMENTATION
- /* Use the intrinsics code by default. */
-# define PNG_ARM_NEON_IMPLEMENTATION 1
-# endif
-#else /* PNG_ARM_NEON_OPT == 0 */
-# define PNG_ARM_NEON_IMPLEMENTATION 0
-#endif /* PNG_ARM_NEON_OPT > 0 */
-
-#ifndef PNG_MIPS_MSA_OPT
-# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \
- defined(PNG_ALIGNED_MEMORY_SUPPORTED)
-# define PNG_MIPS_MSA_OPT 2
-# else
-# define PNG_MIPS_MSA_OPT 0
-# endif
-#endif
-
-#ifndef PNG_MIPS_MMI_OPT
-# ifdef PNG_MIPS_MMI
-# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \
- defined(PNG_ALIGNED_MEMORY_SUPPORTED)
-# define PNG_MIPS_MMI_OPT 1
-# else
-# define PNG_MIPS_MMI_OPT 0
-# endif
-# else
-# define PNG_MIPS_MMI_OPT 0
-# endif
-#endif
-
-#ifndef PNG_POWERPC_VSX_OPT
-# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
-# define PNG_POWERPC_VSX_OPT 2
-# else
-# define PNG_POWERPC_VSX_OPT 0
-# endif
-#endif
-
-#ifndef PNG_LOONGARCH_LSX_OPT
-# if defined(__loongarch_sx)
-# define PNG_LOONGARCH_LSX_OPT 1
-# else
-# define PNG_LOONGARCH_LSX_OPT 0
-# endif
-#endif
-
-#ifndef PNG_INTEL_SSE_OPT
-# ifdef PNG_INTEL_SSE
- /* Only check for SSE if the build configuration has been modified to
- * enable SSE optimizations. This means that these optimizations will
- * be off by default. See contrib/intel for more details.
- */
-# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
- defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
- (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-# define PNG_INTEL_SSE_OPT 1
-# else
-# define PNG_INTEL_SSE_OPT 0
-# endif
-# else
-# define PNG_INTEL_SSE_OPT 0
-# endif
-#endif
-
-#if PNG_INTEL_SSE_OPT > 0
-# ifndef PNG_INTEL_SSE_IMPLEMENTATION
-# if defined(__SSE4_1__) || defined(__AVX__)
- /* We are not actually using AVX, but checking for AVX is the best
- way we can detect SSE4.1 and SSSE3 on MSVC.
- */
-# define PNG_INTEL_SSE_IMPLEMENTATION 3
-# elif defined(__SSSE3__)
-# define PNG_INTEL_SSE_IMPLEMENTATION 2
-# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
- (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
-# define PNG_INTEL_SSE_IMPLEMENTATION 1
-# else
-# define PNG_INTEL_SSE_IMPLEMENTATION 0
-# endif
-# endif
-
-# if PNG_INTEL_SSE_IMPLEMENTATION > 0
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
-# endif
-#else
-# define PNG_INTEL_SSE_IMPLEMENTATION 0
-#endif
-
-#if PNG_MIPS_MSA_OPT > 0
-# ifndef PNG_MIPS_MSA_IMPLEMENTATION
-# if defined(__mips_msa)
-# if defined(__clang__)
-# elif defined(__GNUC__)
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
-# define PNG_MIPS_MSA_IMPLEMENTATION 2
-# endif /* no GNUC support */
-# endif /* __GNUC__ */
-# else /* !defined __mips_msa */
-# define PNG_MIPS_MSA_IMPLEMENTATION 2
-# endif /* __mips_msa */
-# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
-
-# ifndef PNG_MIPS_MSA_IMPLEMENTATION
-# define PNG_MIPS_MSA_IMPLEMENTATION 1
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
-# endif
-#else
-# define PNG_MIPS_MSA_IMPLEMENTATION 0
-#endif /* PNG_MIPS_MSA_OPT > 0 */
-
-#if PNG_MIPS_MMI_OPT > 0
-# ifndef PNG_MIPS_MMI_IMPLEMENTATION
-# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64)
-# define PNG_MIPS_MMI_IMPLEMENTATION 2
-# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */
-# define PNG_MIPS_MMI_IMPLEMENTATION 0
-# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */
-# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */
-
-# if PNG_MIPS_MMI_IMPLEMENTATION > 0
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
-# endif
-#else
-# define PNG_MIPS_MMI_IMPLEMENTATION 0
-#endif /* PNG_MIPS_MMI_OPT > 0 */
-
-#if PNG_POWERPC_VSX_OPT > 0
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
-# define PNG_POWERPC_VSX_IMPLEMENTATION 1
-#else
-# define PNG_POWERPC_VSX_IMPLEMENTATION 0
-#endif
-
-#if PNG_LOONGARCH_LSX_OPT > 0
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx
-# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1
-#else
-# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0
-#endif
-
-#if PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000
-# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_rvv
-# ifndef PNG_RISCV_RVV_IMPLEMENTATION
- /* Use the intrinsics code by default. */
-# define PNG_RISCV_RVV_IMPLEMENTATION 1
-# endif
-#else
-# define PNG_RISCV_RVV_IMPLEMENTATION 0
-#endif /* PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000 */
-
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
* so PNG_BUILD_DLL must be set.
@@ -382,18 +158,12 @@
* always be used to declare an extern data or function object in this file.
*/
#ifndef PNG_INTERNAL_DATA
-# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array
+# define PNG_INTERNAL_DATA(type, name, array) extern type name array
#endif
#ifndef PNG_INTERNAL_FUNCTION
# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
- PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
-#endif
-
-#ifndef PNG_INTERNAL_CALLBACK
-# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
- PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\
- PNG_EMPTY attributes)
+ extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
#endif
/* If floating or fixed point APIs are disabled they may still be compiled
@@ -431,27 +201,48 @@
# define PNG_DLL_EXPORT
#endif
-/* This is a global switch to set the compilation for an installed system
- * (a release build). It can be set for testing debug builds to ensure that
- * they will compile when the build type is switched to RC or STABLE, the
- * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS
- * with either:
- *
- * -DPNG_RELEASE_BUILD Turns on the release compile path
- * -DPNG_RELEASE_BUILD=0 Turns it off
- * or in your pngusr.h with
- * #define PNG_RELEASE_BUILD=1 Turns on the release compile path
- * #define PNG_RELEASE_BUILD=0 Turns it off
- */
-#ifndef PNG_RELEASE_BUILD
-# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
-#endif
-
/* SECURITY and SAFETY:
*
- * libpng is built with support for internal limits on image dimensions and
- * memory usage. These are documented in scripts/pnglibconf.dfa of the
- * source and recorded in the machine generated header file pnglibconf.h.
+ * By default libpng is built without any internal limits on image size,
+ * individual heap (png_malloc) allocations or the total amount of memory used.
+ * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used
+ * (unless individually overridden). These limits are believed to be fairly
+ * safe, but builders of secure systems should verify the values against the
+ * real system capabilities.
+ */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+ /* 'safe' limits */
+# ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000
+# endif
+# ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000
+# endif
+# ifndef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 128
+# endif
+# ifndef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 8000000
+# endif
+#else
+ /* values for no limits */
+# ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 0x7fffffff
+# endif
+# ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 0x7fffffff
+# endif
+# ifndef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 0
+# endif
+# ifndef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 0
+# endif
+#endif
+
+/* Moved to pngpriv.h at libpng-1.5.0 */
+/* NOTE: some of these may have been used in external applications as
+ * these definitions were exposed in pngconf.h prior to 1.5.
*/
/* If you are running on a machine where you cannot allocate more
@@ -494,6 +285,8 @@
#ifdef PNG_WARNINGS_SUPPORTED
# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
#else
+# define png_warning(s1,s2) ((void)(s1))
+# define png_chunk_warning(s1,s2) ((void)(s1))
# define png_warning_parameter(p,number,string) ((void)0)
# define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
# define png_warning_parameter_signed(p,number,format,value) ((void)0)
@@ -501,24 +294,11 @@
# define PNG_WARNING_PARAMETERS(p)
#endif
#ifndef PNG_ERROR_TEXT_SUPPORTED
+# define png_error(s1,s2) png_err(s1)
+# define png_chunk_error(s1,s2) png_err(s1)
# define png_fixed_error(s1,s2) png_err(s1)
#endif
-/* Some fixed point APIs are still required even if not exported because
- * they get used by the corresponding floating point APIs. This magic
- * deals with this:
- */
-#ifdef PNG_FIXED_POINT_SUPPORTED
-# define PNGFAPI PNGAPI
-#else
-# define PNGFAPI /* PRIVATE */
-#endif
-
-#ifndef PNG_VERSION_INFO_ONLY
-/* Other defines specific to compilers can go here. Try to keep
- * them inside an appropriate ifdef/endif pair for portability.
- */
-
/* C allows up-casts from (void*) to any pointer and (const void*) to any
* pointer to a const object. C++ regards this as a type error and requires an
* explicit, static, cast and provides the static_cast<> rune to ensure that
@@ -533,11 +313,25 @@
static_cast(static_cast(value))
#else
# define png_voidcast(type, value) (value)
-# define png_constcast(type, value) ((type)(void*)(const void*)(value))
+# define png_constcast(type, value) ((type)(value))
# define png_aligncast(type, value) ((void*)(value))
# define png_aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */
+/* Some fixed point APIs are still required even if not exported because
+ * they get used by the corresponding floating point APIs. This magic
+ * deals with this:
+ */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+# define PNGFAPI PNGAPI
+#else
+# define PNGFAPI /* PRIVATE */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
/* png.c requires the following ANSI-C constants if the conversion of
@@ -549,12 +343,22 @@
*/
# include
-# include
-
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+ /* We need to check that hasn't already been included earlier
+ * as it seems it doesn't agree with , yet we should really use
+ * if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include
+# endif
+# else
+# include
+# endif
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
- /* Amiga SAS/C: We must include builtin FPU functions when compiling using
- * MATH=68881
- */
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
# include
# endif
#endif
@@ -565,8 +369,9 @@
# include
#endif
-#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
-# include
+#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
+ defined(_WIN32) || defined(__WIN32__)
+# include /* defines _WINDOWS_ macro */
#endif
#endif /* PNG_VERSION_INFO_ONLY */
@@ -575,20 +380,24 @@
* functions that are passed far data must be model-independent.
*/
-/* Platform-independent functions */
+/* Memory model/platform independent fns */
#ifndef PNG_ABORT
-# define PNG_ABORT() abort()
+# ifdef _WINDOWS_
+# define PNG_ABORT() ExitProcess(0)
+# else
+# define PNG_ABORT() abort()
+# endif
#endif
/* These macros may need to be architecture dependent. */
-#define PNG_ALIGN_NONE 0 /* do not use data alignment */
-#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
+#define PNG_ALIGN_NONE 0 /* do not use data alignment */
+#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
#ifdef offsetof
-# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
+# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
#else
# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
#endif
-#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */
+#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */
#ifndef PNG_ALIGN_TYPE
/* Default to using aligned access optimizations and requiring alignment to a
@@ -602,25 +411,25 @@
/* This is used because in some compiler implementations non-aligned
* structure members are supported, so the offsetof approach below fails.
* Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
- * is good for performance. Do not do this unless you have tested the
- * result and understand it.
+ * is good for performance. Do not do this unless you have tested the result
+ * and understand it.
*/
-# define png_alignof(type) (sizeof(type))
+# define png_alignof(type) (sizeof (type))
#else
# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
-# define png_alignof(type) offsetof(struct{char c; type t;}, t)
+# define png_alignof(type) offsetof(struct{char c; type t;}, t)
# else
-# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
-# define png_alignof(type) 1
-# endif
- /* Else leave png_alignof undefined to prevent use thereof */
+# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
+# define png_alignof(type) (1)
+# endif
+ /* Else leave png_alignof undefined to prevent use thereof */
# endif
#endif
-/* This implicitly assumes alignment is always a multiple of 2. */
+/* This implicitly assumes alignment is always to a power of 2. */
#ifdef png_alignof
-# define png_isaligned(ptr, type) \
- (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0)
+# define png_isaligned(ptr, type)\
+ ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
#else
# define png_isaligned(ptr, type) 0
#endif
@@ -637,92 +446,96 @@
* are defined in png.h because they need to be visible to applications
* that call png_set_unknown_chunk().
*/
-/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */
-/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */
-#define PNG_HAVE_IDAT 0x04U
-/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */
-#define PNG_HAVE_IEND 0x10U
- /* 0x20U (unused) */
- /* 0x40U (unused) */
- /* 0x80U (unused) */
-#define PNG_HAVE_CHUNK_HEADER 0x100U
-#define PNG_WROTE_tIME 0x200U
-#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
-#define PNG_BACKGROUND_IS_GRAY 0x800U
-#define PNG_HAVE_PNG_SIGNATURE 0x1000U
-#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
-#define PNG_WROTE_eXIf 0x4000U
-#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */
+/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */
+/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */
+#define PNG_HAVE_IDAT 0x04
+/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */
+#define PNG_HAVE_IEND 0x10
+ /* 0x20 (unused) */
+ /* 0x40 (unused) */
+ /* 0x80 (unused) */
+#define PNG_HAVE_CHUNK_HEADER 0x100
+#define PNG_WROTE_tIME 0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY 0x800
+#define PNG_HAVE_PNG_SIGNATURE 0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+ /* 0x4000 (unused) */
+#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */
/* Flags for the transformations the PNG library does on the image data */
-#define PNG_BGR 0x0001U
-#define PNG_INTERLACE 0x0002U
-#define PNG_PACK 0x0004U
-#define PNG_SHIFT 0x0008U
-#define PNG_SWAP_BYTES 0x0010U
-#define PNG_INVERT_MONO 0x0020U
-#define PNG_QUANTIZE 0x0040U
-#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */
-#define PNG_BACKGROUND_EXPAND 0x0100U
-#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */
-#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */
-#define PNG_RGBA 0x0800U
-#define PNG_EXPAND 0x1000U
-#define PNG_GAMMA 0x2000U
-#define PNG_GRAY_TO_RGB 0x4000U
-#define PNG_FILLER 0x8000U
-#define PNG_PACKSWAP 0x10000U
-#define PNG_SWAP_ALPHA 0x20000U
-#define PNG_STRIP_ALPHA 0x40000U
-#define PNG_INVERT_ALPHA 0x80000U
-#define PNG_USER_TRANSFORM 0x100000U
-#define PNG_RGB_TO_GRAY_ERR 0x200000U
-#define PNG_RGB_TO_GRAY_WARN 0x400000U
-#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
-#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */
-#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */
-#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */
-#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */
- /* 0x8000000U unused */
- /* 0x10000000U unused */
- /* 0x20000000U unused */
- /* 0x40000000U unused */
+#define PNG_BGR 0x0001
+#define PNG_INTERLACE 0x0002
+#define PNG_PACK 0x0004
+#define PNG_SHIFT 0x0008
+#define PNG_SWAP_BYTES 0x0010
+#define PNG_INVERT_MONO 0x0020
+#define PNG_QUANTIZE 0x0040
+#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND 0x0100
+#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA 0x0800
+#define PNG_EXPAND 0x1000
+#define PNG_GAMMA 0x2000
+#define PNG_GRAY_TO_RGB 0x4000
+#define PNG_FILLER 0x8000
+#define PNG_PACKSWAP 0x10000
+#define PNG_SWAP_ALPHA 0x20000
+#define PNG_STRIP_ALPHA 0x40000
+#define PNG_INVERT_ALPHA 0x80000
+#define PNG_USER_TRANSFORM 0x100000
+#define PNG_RGB_TO_GRAY_ERR 0x200000
+#define PNG_RGB_TO_GRAY_WARN 0x400000
+#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */
+ /* 0x8000000 unused */
+ /* 0x10000000 unused */
+ /* 0x20000000 unused */
+ /* 0x40000000 unused */
/* Flags for png_create_struct */
-#define PNG_STRUCT_PNG 0x0001U
-#define PNG_STRUCT_INFO 0x0002U
+#define PNG_STRUCT_PNG 0x0001
+#define PNG_STRUCT_INFO 0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
-#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U
-#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */
- /* 0x0004U unused */
-#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */
- /* 0x0010U unused */
- /* 0x0020U unused */
-#define PNG_FLAG_ROW_INIT 0x0040U
-#define PNG_FLAG_FILLER_AFTER 0x0080U
-#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U
-#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U
-#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U
-#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U
-/* PNG_FLAG_ASSUME_sRGB unused 0x1000U * Added to libpng-1.5.4 */
-#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */
-#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */
-/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */
-/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */
-#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U
- /* 0x40000U unused */
-#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U
-#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */
-#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */
-#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */
- /* 0x800000U unused */
- /* 0x1000000U unused */
- /* 0x2000000U unused */
- /* 0x4000000U unused */
- /* 0x8000000U unused */
- /* 0x10000000U unused */
- /* 0x20000000U unused */
- /* 0x40000000U unused */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
+#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */
+ /* 0x0004 unused */
+#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */
+ /* 0x0010 unused */
+ /* 0x0020 unused */
+#define PNG_FLAG_ROW_INIT 0x0040
+#define PNG_FLAG_FILLER_AFTER 0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
+#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000
+#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */
+ /* 0x800000 unused */
+ /* 0x1000000 unused */
+ /* 0x2000000 unused */
+ /* 0x4000000 unused */
+ /* 0x8000000 unused */
+ /* 0x10000000 unused */
+ /* 0x20000000 unused */
+ /* 0x40000000 unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -753,26 +566,8 @@
/* Added to libpng-1.2.6 JB */
#define PNG_ROWBYTES(pixel_bits, width) \
((pixel_bits) >= 8 ? \
- ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \
- (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) )
-
-/* This returns the number of trailing bits in the last byte of a row, 0 if the
- * last byte is completely full of pixels. It is, in principle, (pixel_bits x
- * width) % 8, but that would overflow for large 'width'. The second macro is
- * the same except that it returns the number of unused bits in the last byte;
- * (8-TRAILBITS), but 0 when TRAILBITS is 0.
- *
- * NOTE: these macros are intended to be self-evidently correct and never
- * overflow on the assumption that pixel_bits is in the range 0..255. The
- * arguments are evaluated only once and they can be signed (e.g. as a result of
- * the integral promotions). The result of the expression always has type
- * (png_uint_32), however the compiler always knows it is in the range 0..7.
- */
-#define PNG_TRAILBITS(pixel_bits, width) \
- (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
-
-#define PNG_PADBITS(pixel_bits, width) \
- ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
+ ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
+ (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
/* PNG_OUT_OF_RANGE returns true if value is outside the range
* ideal-delta..ideal+delta. Each argument is evaluated twice.
@@ -799,7 +594,7 @@
/* The fixed point conversion performs range checking and evaluates
* its argument multiple times, so must be used with care. The
* range checking uses the PNG specification values for a signed
- * 32-bit fixed point value except that the values are deliberately
+ * 32 bit fixed point value except that the values are deliberately
* rounded-to-zero to an integral value - 21474 (21474.83 is roughly
* (2^31-1) * 100000). 's' is a string that describes the value being
* converted.
@@ -815,8 +610,6 @@
#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
-#define png_fixed_ITU(png_ptr, fp, s) ((fp) <= 214748 && (fp) >= 0 ?\
- ((png_uint_32)(10000 * (fp))) : (png_fixed_error(png_ptr, s),0))
#endif
/* else the corresponding function is defined below, inside the scope of the
* cplusplus test.
@@ -835,103 +628,47 @@
*
* PNG_32b correctly produces a value shifted by up to 24 bits, even on
* architectures where (int) is only 16 bits.
- *
- * 1.6.47: PNG_32b was made into a preprocessor evaluable macro by replacing the
- * static_cast with a promoting binary operation using a guaranteed 32-bit
- * (minimum) unsigned value.
*/
-#define PNG_32b(b,s) (((0xFFFFFFFFU)&(b)) << (s))
-#define PNG_U32(b1,b2,b3,b4) \
+#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
+#define PNG_CHUNK(b1,b2,b3,b4) \
(PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
-/* Chunk name validation. When using these macros all the arguments should be
- * constants, otherwise code bloat may well occur. The macros are provided
- * primarily for use in #if checks.
- *
- * PNG_32to8 produces a byte value with the right shift; used to extract the
- * byte value from a chunk name.
- */
-#define PNG_32to8(cn,s) (((cn) >> (s)) & 0xffU)
-#define PNG_CN_VALID_UPPER(b) ((b) >= 65 && (b) <= 90) /* upper-case ASCII */
-#define PNG_CN_VALID_ASCII(b) PNG_CN_VALID_UPPER((b) & ~32U)
-#define PNG_CHUNK_NAME_VALID(cn) (\
- PNG_CN_VALID_ASCII(PNG_32to8(cn,24)) && /* critical, !ancillary */\
- PNG_CN_VALID_ASCII(PNG_32to8(cn,16)) && /* public, !privately defined */\
- PNG_CN_VALID_UPPER(PNG_32to8(cn, 8)) && /* VALID, !reserved */\
- PNG_CN_VALID_ASCII(PNG_32to8(cn, 0)) /* data-dependent, !copy ok */)
-
-/* Constants for known chunk types.
- *
- * MAINTAINERS: If you need to add a chunk, define the name here.
- * For historical reasons these constants have the form png_; i.e.
- * the prefix is lower case. Please use decimal values as the parameters to
- * match the ISO PNG specification and to avoid relying on the C locale
- * interpretation of character values. Please keep the list sorted.
- *
- * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk
- * type. In fact the specification does not express chunk types this way,
- * however using a 32-bit value means that the chunk type can be read from the
- * stream using exactly the same code as used for a 32-bit unsigned value and
- * can be examined far more efficiently (using one arithmetic compare).
- *
- * Prior to 1.5.6 the chunk type constants were expressed as C strings. The
- * libpng API still uses strings for 'unknown' chunks and a macro,
- * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice
- * that for portable code numeric values must still be used; the string "IHDR"
- * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').
- *
- * In 1.7.0 the definitions will be made public in png.h to avoid having to
- * duplicate the same definitions in application code.
- */
-#define png_IDAT PNG_U32( 73, 68, 65, 84)
-#define png_IEND PNG_U32( 73, 69, 78, 68)
-#define png_IHDR PNG_U32( 73, 72, 68, 82)
-#define png_PLTE PNG_U32( 80, 76, 84, 69)
-#define png_acTL PNG_U32( 97, 99, 84, 76) /* PNGv3: APNG */
-#define png_bKGD PNG_U32( 98, 75, 71, 68)
-#define png_cHRM PNG_U32( 99, 72, 82, 77)
-#define png_cICP PNG_U32( 99, 73, 67, 80) /* PNGv3 */
-#define png_cLLI PNG_U32( 99, 76, 76, 73) /* PNGv3 */
-#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
-#define png_fcTL PNG_U32(102, 99, 84, 76) /* PNGv3: APNG */
-#define png_fdAT PNG_U32(102, 100, 65, 84) /* PNGv3: APNG */
-#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
-#define png_gAMA PNG_U32(103, 65, 77, 65)
-#define png_gIFg PNG_U32(103, 73, 70, 103)
-#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */
-#define png_gIFx PNG_U32(103, 73, 70, 120)
-#define png_hIST PNG_U32(104, 73, 83, 84)
-#define png_iCCP PNG_U32(105, 67, 67, 80)
-#define png_iTXt PNG_U32(105, 84, 88, 116)
-#define png_mDCV PNG_U32(109, 68, 67, 86) /* PNGv3 */
-#define png_oFFs PNG_U32(111, 70, 70, 115)
-#define png_pCAL PNG_U32(112, 67, 65, 76)
-#define png_pHYs PNG_U32(112, 72, 89, 115)
-#define png_sBIT PNG_U32(115, 66, 73, 84)
-#define png_sCAL PNG_U32(115, 67, 65, 76)
-#define png_sPLT PNG_U32(115, 80, 76, 84)
-#define png_sRGB PNG_U32(115, 82, 71, 66)
-#define png_sTER PNG_U32(115, 84, 69, 82)
-#define png_tEXt PNG_U32(116, 69, 88, 116)
-#define png_tIME PNG_U32(116, 73, 77, 69)
-#define png_tRNS PNG_U32(116, 82, 78, 83)
-#define png_zTXt PNG_U32(122, 84, 88, 116)
+#define png_IHDR PNG_CHUNK( 73, 72, 68, 82)
+#define png_IDAT PNG_CHUNK( 73, 68, 65, 84)
+#define png_IEND PNG_CHUNK( 73, 69, 78, 68)
+#define png_PLTE PNG_CHUNK( 80, 76, 84, 69)
+#define png_bKGD PNG_CHUNK( 98, 75, 71, 68)
+#define png_cHRM PNG_CHUNK( 99, 72, 82, 77)
+#define png_gAMA PNG_CHUNK(103, 65, 77, 65)
+#define png_hIST PNG_CHUNK(104, 73, 83, 84)
+#define png_iCCP PNG_CHUNK(105, 67, 67, 80)
+#define png_iTXt PNG_CHUNK(105, 84, 88, 116)
+#define png_oFFs PNG_CHUNK(111, 70, 70, 115)
+#define png_pCAL PNG_CHUNK(112, 67, 65, 76)
+#define png_sCAL PNG_CHUNK(115, 67, 65, 76)
+#define png_pHYs PNG_CHUNK(112, 72, 89, 115)
+#define png_sBIT PNG_CHUNK(115, 66, 73, 84)
+#define png_sPLT PNG_CHUNK(115, 80, 76, 84)
+#define png_sRGB PNG_CHUNK(115, 82, 71, 66)
+#define png_sTER PNG_CHUNK(115, 84, 69, 82)
+#define png_tEXt PNG_CHUNK(116, 69, 88, 116)
+#define png_tIME PNG_CHUNK(116, 73, 77, 69)
+#define png_tRNS PNG_CHUNK(116, 82, 78, 83)
+#define png_zTXt PNG_CHUNK(122, 84, 88, 116)
/* The following will work on (signed char*) strings, whereas the get_uint_32
* macro will fail on top-bit-set values because of the sign extension.
*/
#define PNG_CHUNK_FROM_STRING(s)\
- PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3])
+ PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
* signed and the argument is a (char[]) This macro will fail miserably on
* systems where (char) is more than 8 bits.
*/
#define PNG_STRING_FROM_CHUNK(s,c)\
- (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \
- ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\
- ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \
- ((char*)(s))[3]=(char)((c & 0xff)))
+ (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
+ ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
/* Do the same but terminate with a null character. */
#define PNG_CSTRING_FROM_CHUNK(s,c)\
@@ -944,74 +681,11 @@
#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13))
#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5))
-/* Known chunks. All supported chunks must be listed here. The macro PNG_CHUNK
- * contains the four character ASCII name by which the chunk is identified. The
- * macro is implemented as required to build tables or switch statements which
- * require entries for every known chunk. The macro also contains an index
- * value which should be in order (this is checked in png.c).
- *
- * Notice that "known" does not require "SUPPORTED"; tables should be built in
- * such a way that chunks unsupported in a build require no more than the table
- * entry (which should be small.) In particular function pointers for
- * unsupported chunks should be NULL.
- *
- * At present these index values are not exported (not part of the public API)
- * so can be changed at will. For convenience the names are in lexical sort
- * order but with the critical chunks at the start in the order of occurence in
- * a PNG.
- *
- * PNG_INFO_ values do not exist for every one of these chunk handles; for
- * example PNG_INFO_{IDAT,IEND,tEXt,iTXt,zTXt} and possibly other chunks in the
- * future.
- */
-#define PNG_KNOWN_CHUNKS\
- PNG_CHUNK(IHDR, 0)\
- PNG_CHUNK(PLTE, 1)\
- PNG_CHUNK(IDAT, 2)\
- PNG_CHUNK(IEND, 3)\
- PNG_CHUNK(acTL, 4)\
- PNG_CHUNK(bKGD, 5)\
- PNG_CHUNK(cHRM, 6)\
- PNG_CHUNK(cICP, 7)\
- PNG_CHUNK(cLLI, 8)\
- PNG_CHUNK(eXIf, 9)\
- PNG_CHUNK(fcTL, 10)\
- PNG_CHUNK(fdAT, 11)\
- PNG_CHUNK(gAMA, 12)\
- PNG_CHUNK(hIST, 13)\
- PNG_CHUNK(iCCP, 14)\
- PNG_CHUNK(iTXt, 15)\
- PNG_CHUNK(mDCV, 16)\
- PNG_CHUNK(oFFs, 17)\
- PNG_CHUNK(pCAL, 18)\
- PNG_CHUNK(pHYs, 19)\
- PNG_CHUNK(sBIT, 20)\
- PNG_CHUNK(sCAL, 21)\
- PNG_CHUNK(sPLT, 22)\
- PNG_CHUNK(sRGB, 23)\
- PNG_CHUNK(tEXt, 24)\
- PNG_CHUNK(tIME, 25)\
- PNG_CHUNK(tRNS, 26)\
- PNG_CHUNK(zTXt, 27)
-
/* Gamma values (new at libpng-1.5.4): */
#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */
#define PNG_GAMMA_MAC_INVERSE 65909
#define PNG_GAMMA_sRGB_INVERSE 45455
-/* gamma sanity check. libpng cannot implement gamma transforms outside a
- * certain limit because of its use of 16-bit fixed point intermediate values.
- * Gamma values that are too large or too small will zap the 16-bit values all
- * to 0 or 65535 resulting in an obvious 'bad' image.
- *
- * In libpng 1.6.0 the limits were changed from 0.07..3 to 0.01..100 to
- * accommodate the optimal 16-bit gamma of 36 and its reciprocal.
- *
- * These are png_fixed_point integral values:
- */
-#define PNG_LIB_GAMMA_MIN 1000
-#define PNG_LIB_GAMMA_MAX 10000000
-
/* Almost everything below is C specific; the #defines above can be used in
* non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
*/
@@ -1020,23 +694,7 @@
#include "pngstruct.h"
#include "pnginfo.h"
-/* Validate the include paths - the include path used to generate pnglibconf.h
- * must match that used in the build, or we must be using pnglibconf.h.prebuilt:
- */
-#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
-# error The include path of is incorrect
- /* When pnglibconf.h was built, the copy of zlib.h that it used was not the
- * same as the one being used here. Considering how libpng makes decisions
- * to use the zlib API based on the zlib version number, the -I options must
- * match.
- *
- * A possible cause of this mismatch is that you passed an -I option in
- * CFLAGS, which is unlikely to work. All the preprocessor options, and all
- * the -I options in particular, should be in CPPFLAGS.
- */
-#endif
-
-/* This is used for 16-bit gamma tables -- only the top level pointers are
+/* This is used for 16 bit gamma tables -- only the top level pointers are
* const; this could be changed:
*/
typedef const png_uint_16p * png_const_uint_16pp;
@@ -1054,13 +712,12 @@ PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);
PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
-#define PNG_sRGB_FROM_LINEAR(linear) \
- ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \
- + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)))
+#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
+ ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
/* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
* encoded value with maximum error 0.646365. Note that the input is not a
* 16-bit value; it has been multiplied by 255! */
-#endif /* SIMPLIFIED_READ/WRITE */
+#endif /* PNG_SIMPLIFIED_READ/WRITE */
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
@@ -1073,19 +730,18 @@ extern "C" {
*
* All of these functions must be declared with PNG_INTERNAL_FUNCTION.
*/
+
/* Zlib support */
#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
-PNG_INTERNAL_FUNCTION(void, png_zstream_error,
- (png_structrp png_ptr, int ret),
+PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
PNG_EMPTY);
/* Used by the zlib handling functions to ensure that z_stream::msg is always
* set before they return.
*/
#ifdef PNG_WRITE_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_free_buffer_list,
- (png_structrp png_ptr, png_compression_bufferp *list),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+ png_compression_bufferp *list),PNG_EMPTY);
/* Free the buffer list used by the compressed write code. */
#endif
@@ -1093,75 +749,41 @@ PNG_INTERNAL_FUNCTION(void, png_free_buffer_list,
!defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
(defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
- defined(PNG_mDCV_SUPPORTED) || \
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
(defined(PNG_sCAL_SUPPORTED) && \
defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
-PNG_INTERNAL_FUNCTION(png_fixed_point, png_fixed,
- (png_const_structrp png_ptr, double fp, png_const_charp text),
- PNG_EMPTY);
-#endif
-
-#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
- !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
- (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
-PNG_INTERNAL_FUNCTION(png_uint_32, png_fixed_ITU,
- (png_const_structrp png_ptr, double fp, png_const_charp text),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
+ double fp, png_const_charp text),PNG_EMPTY);
#endif
/* Check the user version string for compatibility, returns false if the version
* numbers aren't compatible.
*/
-PNG_INTERNAL_FUNCTION(int, png_user_version_check,
- (png_structrp png_ptr, png_const_charp user_png_ver),
- PNG_EMPTY);
-
-#ifdef PNG_READ_SUPPORTED /* should only be used on read */
-/* Security: read limits on the largest allocations while reading a PNG. This
- * avoids very large allocations caused by PNG files with damaged or altered
- * chunk 'length' fields.
- */
-#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* run-time limit */
-# define png_chunk_max(png_ptr) ((png_ptr)->user_chunk_malloc_max)
-
-#elif PNG_USER_CHUNK_MALLOC_MAX > 0 /* compile-time limit */
-# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_USER_CHUNK_MALLOC_MAX)
-
-#elif (defined PNG_MAX_MALLOC_64K) /* legacy system limit */
-# define png_chunk_max(png_ptr) ((void)png_ptr, 65536U)
-
-#else /* modern system limit SIZE_MAX (C99) */
-# define png_chunk_max(png_ptr) ((void)png_ptr, PNG_SIZE_MAX)
-#endif
-#endif /* READ */
+PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+ png_const_charp user_png_ver),PNG_EMPTY);
/* Internal base allocator - no messages, NULL on failure to allocate. This
* does, however, call the application provided allocator and that could call
* png_error (although that would be a bug in the application implementation.)
*/
-PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_base,
- (png_const_structrp png_ptr, png_alloc_size_t size),
- PNG_ALLOCATED);
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
+ png_alloc_size_t size),PNG_ALLOCATED);
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
/* Internal array allocator, outputs no error or warning messages on failure,
- * just returns NULL.
+ * just returns NULL.
*/
-PNG_INTERNAL_FUNCTION(png_voidp, png_malloc_array,
- (png_const_structrp png_ptr, int nelements, size_t element_size),
- PNG_ALLOCATED);
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
+ int nelements, size_t element_size),PNG_ALLOCATED);
/* The same but an existing array is extended by add_elements. This function
* also memsets the new elements to 0 and copies the old elements. The old
* array is not freed or altered.
*/
-PNG_INTERNAL_FUNCTION(png_voidp, png_realloc_array,
- (png_const_structrp png_ptr,
- png_const_voidp array, int old_elements, int add_elements,
- size_t element_size),
- PNG_ALLOCATED);
+PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+ png_const_voidp array, int old_elements, int add_elements,
+ size_t element_size),PNG_ALLOCATED);
#endif /* text, sPLT or unknown chunks */
/* Magic to create a struct when there is no struct to call the user supplied
@@ -1170,106 +792,87 @@ PNG_INTERNAL_FUNCTION(png_voidp, png_realloc_array,
* restriction so libpng has to assume that the 'free' handler, at least, might
* call png_error.
*/
-PNG_INTERNAL_FUNCTION(png_structp, png_create_png_struct,
- (png_const_charp user_png_ver,
- png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn,
- png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED);
+PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
+ png_free_ptr free_fn),PNG_ALLOCATED);
/* Free memory from internal libpng struct */
-PNG_INTERNAL_FUNCTION(void, png_destroy_png_struct,
- (png_structrp png_ptr),
+PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
PNG_EMPTY);
/* Free an allocated jmp_buf (always succeeds) */
-PNG_INTERNAL_FUNCTION(void, png_free_jmpbuf,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
/* Function to allocate memory for zlib. PNGAPI is disallowed. */
-PNG_INTERNAL_FUNCTION(voidpf, png_zalloc,
- (voidpf png_ptr, uInt items, uInt size),
+PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
PNG_ALLOCATED);
/* Function to free memory for zlib. PNGAPI is disallowed. */
-PNG_INTERNAL_FUNCTION(void, png_zfree,
- (voidpf png_ptr, voidpf ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
/* Next four functions are used internally as callbacks. PNGCBAPI is required
* but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to
* PNGCBAPI at 1.5.0
*/
-PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_read_data,
- (png_structp png_ptr, png_bytep data, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_push_fill_buffer,
- (png_structp png_ptr, png_bytep buffer, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
+ png_bytep buffer, png_size_t length),PNG_EMPTY);
#endif
-PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_write_data,
- (png_structp png_ptr, png_bytep data, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
#ifdef PNG_WRITE_FLUSH_SUPPORTED
# ifdef PNG_STDIO_SUPPORTED
-PNG_INTERNAL_FUNCTION(void PNGCBAPI, png_default_flush,
- (png_structp png_ptr),
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
PNG_EMPTY);
# endif
#endif
/* Reset the CRC variable */
-PNG_INTERNAL_FUNCTION(void, png_reset_crc,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
/* Write the "data" buffer to whatever output you are using */
-PNG_INTERNAL_FUNCTION(void, png_write_data,
- (png_structrp png_ptr, png_const_bytep data, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
+ png_const_bytep data, png_size_t length),PNG_EMPTY);
/* Read and check the PNG file signature */
-PNG_INTERNAL_FUNCTION(void, png_read_sig,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
/* Read the chunk header (length + type name) */
-PNG_INTERNAL_FUNCTION(png_uint_32, png_read_chunk_header,
- (png_structrp png_ptr),
+PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
PNG_EMPTY);
/* Read data from whatever input you are using into the "data" buffer */
-PNG_INTERNAL_FUNCTION(void, png_read_data,
- (png_structrp png_ptr, png_bytep data, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
+ png_size_t length),PNG_EMPTY);
/* Read bytes into buf, and update png_ptr->crc */
-PNG_INTERNAL_FUNCTION(void, png_crc_read,
- (png_structrp png_ptr, png_bytep buf, png_uint_32 length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
+ png_uint_32 length),PNG_EMPTY);
/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
-PNG_INTERNAL_FUNCTION(int, png_crc_finish,
- (png_structrp png_ptr, png_uint_32 skip),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
+ png_uint_32 skip),PNG_EMPTY);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
/* Calculate the CRC over a section of data. Note that we are only
* passing a maximum of 64K on systems that have this as a memory limit,
* since this is the maximum buffer size we can specify.
*/
-PNG_INTERNAL_FUNCTION(void, png_calculate_crc,
- (png_structrp png_ptr, png_const_bytep ptr, size_t length),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
+ png_const_bytep ptr, png_size_t length),PNG_EMPTY);
#ifdef PNG_WRITE_FLUSH_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_flush,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
#endif
/* Write various chunks */
@@ -1277,193 +880,126 @@ PNG_INTERNAL_FUNCTION(void, png_flush,
/* Write the IHDR chunk, and update the png_struct with the necessary
* information.
*/
-PNG_INTERNAL_FUNCTION(void, png_write_IHDR,
- (png_structrp png_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
- int compression_method, int filter_method, int interlace_method),
+PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
+ int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
+ png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
+ png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_write_PLTE,
- (png_structrp png_ptr,
- png_const_colorp palette, png_uint_32 num_pal),
- PNG_EMPTY);
-
-PNG_INTERNAL_FUNCTION(void, png_compress_IDAT,
- (png_structrp png_ptr,
- png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
- PNG_EMPTY);
-
-PNG_INTERNAL_FUNCTION(void, png_write_IEND,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
#ifdef PNG_WRITE_gAMA_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_gAMA_fixed,
- (png_structrp png_ptr, png_fixed_point file_gamma),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
+ png_fixed_point file_gamma),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_sBIT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_sBIT,
- (png_structrp png_ptr, png_const_color_8p sbit, int color_type),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
+ png_const_color_8p sbit, int color_type),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_cHRM_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_cHRM_fixed,
- (png_structrp png_ptr, const png_xy *xy),
- PNG_EMPTY);
- /* The xy value must have been previously validated */
-#endif
-
-#ifdef PNG_WRITE_cICP_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_cICP,
- (png_structrp png_ptr,
- png_byte colour_primaries, png_byte transfer_function,
- png_byte matrix_coefficients, png_byte video_full_range_flag),
- PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_cLLI_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_cLLI_fixed,
- (png_structrp png_ptr, png_uint_32 maxCLL, png_uint_32 maxFALL),
- PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_mDCV_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_mDCV_fixed,
- (png_structrp png_ptr,
- png_uint_16 red_x, png_uint_16 red_y,
- png_uint_16 green_x, png_uint_16 green_y,
- png_uint_16 blue_x, png_uint_16 blue_y,
- png_uint_16 white_x, png_uint_16 white_y,
- png_uint_32 maxDL, png_uint_32 minDL),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
+ const png_xy *xy), PNG_EMPTY);
+ /* The xy value must have been previously validated */
#endif
#ifdef PNG_WRITE_sRGB_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_sRGB,
- (png_structrp png_ptr, int intent),
- PNG_EMPTY);
-#endif
-
-#ifdef PNG_WRITE_eXIf_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_eXIf,
- (png_structrp png_ptr, png_bytep exif, int num_exif),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
+ int intent),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_iCCP_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_iCCP,
- (png_structrp png_ptr,
- png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
- PNG_EMPTY);
- /* Writes a previously 'set' profile. The profile argument is **not**
- * compressed.
+PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+ png_const_charp name, png_const_bytep profile), PNG_EMPTY);
+ /* The profile must have been previously validated for correctness, the
+ * length comes from the first four bytes. Only the base, deflate,
+ * compression is supported.
*/
#endif
#ifdef PNG_WRITE_sPLT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_sPLT,
- (png_structrp png_ptr, png_const_sPLT_tp palette),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
+ png_const_sPLT_tp palette),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_tRNS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_tRNS,
- (png_structrp png_ptr,
+PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
png_const_bytep trans, png_const_color_16p values, int number,
- int color_type),
- PNG_EMPTY);
+ int color_type),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_bKGD_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_bKGD,
- (png_structrp png_ptr, png_const_color_16p values, int color_type),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
+ png_const_color_16p values, int color_type),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_hIST_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_hIST,
- (png_structrp png_ptr, png_const_uint_16p hist, int num_hist),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
+ png_const_uint_16p hist, int num_hist),PNG_EMPTY);
#endif
/* Chunks that have keywords */
#ifdef PNG_WRITE_tEXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_tEXt,
- (png_structrp png_ptr,
- png_const_charp key, png_const_charp text, size_t text_len),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
+ png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_zTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_zTXt,
- (png_structrp png_ptr,
- png_const_charp key, png_const_charp text, int compression),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
+ key, png_const_charp text, png_size_t text_len, int compression),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_iTXt_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_iTXt,
- (png_structrp png_ptr,
+PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
int compression, png_const_charp key, png_const_charp lang,
- png_const_charp lang_key, png_const_charp text),
- PNG_EMPTY);
+ png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
#endif
#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
-PNG_INTERNAL_FUNCTION(int, png_set_text_2,
- (png_const_structrp png_ptr,
- png_inforp info_ptr, png_const_textp text_ptr, int num_text),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_oFFs_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_oFFs,
- (png_structrp png_ptr,
- png_int_32 x_offset, png_int_32 y_offset, int unit_type),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_pCAL_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_pCAL,
- (png_structrp png_ptr,
- png_charp purpose, png_int_32 X0, png_int_32 X1,
- int type, int nparams, png_const_charp units, png_charpp params),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_const_charp units, png_charpp params),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_pHYs_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_pHYs,
- (png_structrp png_ptr,
+PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
- int unit_type),
- PNG_EMPTY);
+ int unit_type),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_tIME_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_tIME,
- (png_structrp png_ptr, png_const_timep mod_time),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
+ png_const_timep mod_time),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_sCAL_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_write_sCAL_s,
- (png_structrp png_ptr,
- int unit, png_const_charp width, png_const_charp height),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
+ int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
#endif
/* Called when finished processing a row of data */
-PNG_INTERNAL_FUNCTION(void, png_write_finish_row,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
/* Internal use only. Called before first row of data */
-PNG_INTERNAL_FUNCTION(void, png_write_start_row,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+ PNG_EMPTY);
/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an
* array of png_ptr->width pixels. If the image is not interlaced or this
@@ -1491,9 +1027,8 @@ PNG_INTERNAL_FUNCTION(void, png_write_start_row,
#ifndef PNG_USE_COMPILE_TIME_MASKS
# define PNG_USE_COMPILE_TIME_MASKS 1
#endif
-PNG_INTERNAL_FUNCTION(void, png_combine_row,
- (png_const_structrp png_ptr, png_bytep row, int display),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+ png_bytep row, int display),PNG_EMPTY);
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* Expand an interlaced row: the 'row_info' describes the pass data that has
@@ -1502,439 +1037,507 @@ PNG_INTERNAL_FUNCTION(void, png_combine_row,
* the pixels are *replicated* to the intervening space. This is essential for
* the correct operation of png_combine_row, above.
*/
-PNG_INTERNAL_FUNCTION(void, png_do_read_interlace,
- (png_row_infop row_info,
- png_bytep row, int pass, png_uint_32 transformations),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
#endif
/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Grab pixels out of a row for an interlaced pass */
-PNG_INTERNAL_FUNCTION(void, png_do_write_interlace,
- (png_row_infop row_info, png_bytep row, int pass),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
+ png_bytep row, int pass),PNG_EMPTY);
#endif
/* Unfilter a row: check the filter value before calling this, there is no point
* calling it for PNG_FILTER_VALUE_NONE.
*/
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row,
- (png_structrp pp, png_row_infop row_info,
- png_bytep row, png_const_bytep prev_row, int filter),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
-#if PNG_ARM_NEON_OPT > 0
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_neon,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_MIPS_MSA_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_msa,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_MIPS_MMI_IMPLEMENTATION > 0
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_mmi,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_POWERPC_VSX_OPT > 0
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_vsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_INTEL_SSE_IMPLEMENTATION > 0
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_sse2,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_lsx,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
-
-#if PNG_RISCV_RVV_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_up_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub3_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_sub4_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg3_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_avg4_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth3_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_filter_row_paeth4_rvv,
- (png_row_infop row_info, png_bytep row, png_const_bytep prev_row),
- PNG_EMPTY);
-#endif
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
/* Choose the best filter to use and filter the row data */
-PNG_INTERNAL_FUNCTION(void, png_write_find_filter,
- (png_structrp png_ptr, png_row_infop row_info),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_read_IDAT_data,
- (png_structrp png_ptr, png_bytep output, png_alloc_size_t avail_out),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
+ png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
/* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer
* is NULL the function checks, instead, for the end of the stream. In this
* case a benign error will be issued if the stream end is not found or if
* extra data has to be consumed.
*/
-PNG_INTERNAL_FUNCTION(void, png_read_finish_IDAT,
- (png_structrp png_ptr),
+PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
PNG_EMPTY);
/* This cleans up when the IDAT LZ stream does not end when the last image
* byte is read; there is still some pending input.
*/
-PNG_INTERNAL_FUNCTION(void, png_read_finish_row,
- (png_structrp png_ptr),
+PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
PNG_EMPTY);
/* Finish a row while reading, dealing with interlacing passes, etc. */
-#endif /* SEQUENTIAL_READ */
+#endif
/* Initialize the row buffers, etc. */
-PNG_INTERNAL_FUNCTION(void, png_read_start_row,
- (png_structrp png_ptr),
- PNG_EMPTY);
-
-#if ZLIB_VERNUM >= 0x1240
-PNG_INTERNAL_FUNCTION(int, png_zlib_inflate,
- (png_structrp png_ptr, int flush),
- PNG_EMPTY);
-# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
-#else /* Zlib < 1.2.4 */
-# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
-#endif /* Zlib < 1.2.4 */
+PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Optional call to update the users info structure */
-PNG_INTERNAL_FUNCTION(void, png_read_transform_info,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+#endif
+
+/* These are the functions that do the transformations */
+#ifdef PNG_READ_FILLER_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_filler,(png_row_infop row_info,
+ png_bytep row, png_uint_32 filler, png_uint_32 flags),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_swap_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_swap_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_invert_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_invert_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
#endif
-/* Shared transform functions, defined in pngtran.c */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_strip_channel,
- (png_row_infop row_info, png_bytep row, int at_start),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
+ png_bytep row, int at_start),PNG_EMPTY);
#endif
#ifdef PNG_16BIT_SUPPORTED
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_swap,
- (png_row_infop row_info, png_bytep row),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
#endif
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_packswap,
- (png_row_infop row_info, png_bytep row),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_do_rgb_to_gray,(png_structrp png_ptr,
+ png_row_infop row_info, png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_gray_to_rgb,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_unpack,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_unshift,(png_row_infop row_info,
+ png_bytep row, png_const_color_8p sig_bits),PNG_EMPTY);
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_invert,
- (png_row_infop row_info, png_bytep row),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_scale_16_to_8,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_chop,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_quantize,(png_row_infop row_info,
+ png_bytep row, png_const_bytep palette_lookup,
+ png_const_bytep quantize_lookup),PNG_EMPTY);
+
+# ifdef PNG_CORRECT_PALETTE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_correct_palette,(png_structrp png_ptr,
+ png_colorp palette, int num_palette),PNG_EMPTY);
+# endif
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_bgr,
- (png_row_infop row_info, png_bytep row),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_pack,(png_row_infop row_info,
+ png_bytep row, png_uint_32 bit_depth),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_shift,(png_row_infop row_info,
+ png_bytep row, png_const_color_8p bit_depth),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_compose,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_gamma,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_encode_alpha,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_expand_palette,(png_row_infop row_info,
+ png_bytep row, png_const_colorp palette, png_const_bytep trans,
+ int num_trans),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_expand,(png_row_infop row_info,
+ png_bytep row, png_const_color_16p trans_color),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_expand_16,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
#endif
/* The following decodes the appropriate chunks, and does error correction,
* then calls the appropriate callback for the chunk if it is valid.
*/
-typedef enum
-{
- /* Result of a call to png_handle_chunk made to handle the current chunk
- * png_struct::chunk_name on read. Always informational, either the stream
- * is read for the next chunk or the routine will call png_error.
- *
- * NOTE: order is important internally. handled_saved and above are regarded
- * as handling the chunk.
- */
- handled_error = 0, /* bad crc or known and bad format or too long */
- handled_discarded, /* not saved in the unknown chunk list */
- handled_saved, /* saved in the unknown chunk list */
- handled_ok /* known, supported and handled without error */
-} png_handle_result_code;
-PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_unknown,
- (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),
- PNG_EMPTY);
+/* Decode the IHDR chunk */
+PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
+ png_uint_32 chunk_name),PNG_EMPTY);
+
+#ifdef PNG_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
/* This is the function that gets called for unknown chunks. The 'keep'
* argument is either non-zero for a known chunk that has been set to be
* handled as unknown or zero for an unknown chunk. By default the function
* just skips the chunk or errors out if it is critical.
*/
-PNG_INTERNAL_FUNCTION(png_handle_result_code, png_handle_chunk,
- (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),
- PNG_EMPTY);
- /* This handles the current chunk png_ptr->chunk_name with unread
- * data[length] and returns one of the above result codes.
- */
-
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
- defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
-PNG_INTERNAL_FUNCTION(int, png_chunk_unknown_handling,
- (png_const_structrp png_ptr, png_uint_32 chunk_name),
- PNG_EMPTY);
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+ (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
/* Exactly as the API png_handle_as_unknown() except that the argument is a
* 32-bit chunk name, not a string.
*/
-#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+#endif
+#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
/* Handle the transformations for reading and writing */
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_do_read_transformations,
- (png_structrp png_ptr, png_row_infop row_info),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_do_write_transformations,
- (png_structrp png_ptr, png_row_infop row_info),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
#endif
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_init_read_transformations,
- (png_structrp png_ptr),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
+ PNG_EMPTY);
#endif
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_push_read_chunk,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_read_sig,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_check_crc,
- (png_structrp png_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_save_buffer,
- (png_structrp png_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_restore_buffer,
- (png_structrp png_ptr, png_bytep buffer, size_t buffer_length),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_read_IDAT,
- (png_structrp png_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_process_IDAT_data,
- (png_structrp png_ptr, png_bytep buffer, size_t buffer_length),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_process_row,
- (png_structrp png_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_have_info,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_have_end,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_have_row,
- (png_structrp png_ptr, png_bytep row),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_push_read_end,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_process_some_data,
- (png_structrp png_ptr, png_inforp info_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_read_push_finish_row,
- (png_structrp png_ptr),
- PNG_EMPTY);
-#endif /* PROGRESSIVE_READ */
+PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr,
+ png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
+ png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+# ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_intrapixel,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_write_intrapixel,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+/* Added at libpng version 1.6.0 */
+#ifdef PNG_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);
+ /* Set the colorspace gamma with a value provided by the application or by
+ * the gAMA chunk on read. The value will override anything set by an ICC
+ * profile.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Synchronize the info 'valid' flags with the colorspace */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Copy the png_struct colorspace to the info_struct and call the above to
+ * synchronize the flags. Checks for NULL info_ptr and does nothing.
+ */
+#endif
+
+/* Added at libpng version 1.4.0 */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* These internal functions are for maintaining the colorspace structure within
+ * a png_info or png_struct (or, indeed, both).
+ */
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,
+ int preferred), PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,
+ int preferred), PNG_EMPTY);
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, int intent), PNG_EMPTY);
+ /* This does set the colorspace gAMA and cHRM values too, but doesn't set the
+ * flags to write them, if it returns false there was a problem and an error
+ * message has already been output (but the colorspace may still need to be
+ * synced to record the invalid flag).
+ */
+#endif /* sRGB */
#ifdef PNG_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length, png_const_bytep profile, int color_type),
+ PNG_EMPTY);
+ /* The 'name' is used for information only */
+
/* Routines for checking parts of an ICC profile. */
-#ifdef PNG_READ_iCCP_SUPPORTED
-PNG_INTERNAL_FUNCTION(int, png_icc_check_length,
- (png_const_structrp png_ptr,
- png_const_charp name, png_uint_32 profile_length),
- PNG_EMPTY);
-#endif /* READ_iCCP */
-PNG_INTERNAL_FUNCTION(int, png_icc_check_header,
- (png_const_structrp png_ptr,
- png_const_charp name, png_uint_32 profile_length,
- png_const_bytep profile /* first 132 bytes only */, int color_type),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(int, png_icc_check_tag_table,
- (png_const_structrp png_ptr,
- png_const_charp name, png_uint_32 profile_length,
- png_const_bytep profile /* header plus whole tag table */),
+PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length), PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* first 132 bytes only */, int color_type),
PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
+ png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_bytep profile, uLong adler), PNG_EMPTY);
+ /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
+ * be zero to indicate that it is not available. It is used, if provided,
+ * as a fast check on the profile when checking to see if it is sRGB.
+ */
+#endif
#endif /* iCCP */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients,
- (png_structrp png_ptr),
- PNG_EMPTY);
- /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,
+ (png_structrp png_ptr), PNG_EMPTY);
+ /* Set the rgb_to_gray coefficients from the colorspace Y values */
#endif /* READ_RGB_TO_GRAY */
+#endif /* COLORSPACE */
/* Added at libpng version 1.4.0 */
-PNG_INTERNAL_FUNCTION(void, png_check_IHDR,
- (png_const_structrp png_ptr,
- png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
- int interlace_type, int compression_type, int filter_type),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type),PNG_EMPTY);
/* Added at libpng version 1.5.10 */
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_do_check_palette_indexes,
- (png_structrp png_ptr, png_row_infop row_info),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
+ (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
#endif
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
-PNG_INTERNAL_FUNCTION(void, png_fixed_error,
- (png_const_structrp png_ptr, png_const_charp name),
- PNG_NORETURN);
+PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
+ png_const_charp name),PNG_NORETURN);
#endif
/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
* the end. Always leaves the buffer nul terminated. Never errors out (and
* there is no error code.)
*/
-PNG_INTERNAL_FUNCTION(size_t, png_safecat,
- (png_charp buffer, size_t bufsize, size_t pos, png_const_charp string),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+ size_t pos, png_const_charp string),PNG_EMPTY);
/* Various internal functions to handle formatted warning messages, currently
* only implemented for warnings.
@@ -1945,9 +1548,8 @@ PNG_INTERNAL_FUNCTION(size_t, png_safecat,
* Returns the pointer to the start of the formatted string. This utility only
* does unsigned values.
*/
-PNG_INTERNAL_FUNCTION(png_charp, png_format_number,
- (png_const_charp start, png_charp end, int format, png_alloc_size_t number),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+ png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
/* Convenience macro that takes an array: */
#define PNG_FORMAT_NUMBER(buffer,format,number) \
@@ -1979,26 +1581,23 @@ PNG_INTERNAL_FUNCTION(png_charp, png_format_number,
typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
PNG_WARNING_PARAMETER_SIZE];
-PNG_INTERNAL_FUNCTION(void, png_warning_parameter,
- (png_warning_parameters p, int number, png_const_charp string),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
+ int number, png_const_charp string),PNG_EMPTY);
/* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
* including the trailing '\0'.
*/
-PNG_INTERNAL_FUNCTION(void, png_warning_parameter_unsigned,
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
(png_warning_parameters p, int number, int format, png_alloc_size_t value),
PNG_EMPTY);
/* Use png_alloc_size_t because it is an unsigned type as big as any we
* need to output. Use the following for a signed value.
*/
-PNG_INTERNAL_FUNCTION(void, png_warning_parameter_signed,
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
(png_warning_parameters p, int number, int format, png_int_32 value),
PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_formatted_warning,
- (png_const_structrp png_ptr,
- png_warning_parameters p, png_const_charp message),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+ png_warning_parameters p, png_const_charp message),PNG_EMPTY);
/* 'message' follows the X/Open approach of using @1, @2 to insert
* parameters previously supplied using the above functions. Errors in
* specifying the parameters will simply result in garbage substitutions.
@@ -2020,16 +1619,14 @@ PNG_INTERNAL_FUNCTION(void, png_formatted_warning,
* If benign errors aren't supported they end up as the corresponding base call
* (png_warning or png_error.)
*/
-PNG_INTERNAL_FUNCTION(void, png_app_warning,
- (png_const_structrp png_ptr, png_const_charp message),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
/* The application provided invalid parameters to an API function or called
* an API function at the wrong time, libpng can completely recover.
*/
-PNG_INTERNAL_FUNCTION(void, png_app_error,
- (png_const_structrp png_ptr, png_const_charp message),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
/* As above but libpng will ignore the call, or attempt some other partial
* recovery from the error.
*/
@@ -2038,9 +1635,8 @@ PNG_INTERNAL_FUNCTION(void, png_app_error,
# define png_app_error(pp,s) png_error(pp,s)
#endif
-PNG_INTERNAL_FUNCTION(void, png_chunk_report,
- (png_const_structrp png_ptr, png_const_charp message, int error),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+ png_const_charp message, int error),PNG_EMPTY);
/* Report a recoverable issue in chunk data. On read this is used to report
* a problem found while reading a particular chunk and the
* png_chunk_benign_error or png_chunk_warning function is used as
@@ -2066,17 +1662,14 @@ PNG_INTERNAL_FUNCTION(void, png_chunk_report,
#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
#ifdef PNG_FLOATING_POINT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_ascii_from_fp,
- (png_const_structrp png_ptr,
- png_charp ascii, size_t size, double fp, unsigned int precision),
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, double fp, unsigned int precision),
PNG_EMPTY);
#endif /* FLOATING_POINT */
#ifdef PNG_FIXED_POINT_SUPPORTED
-PNG_INTERNAL_FUNCTION(void, png_ascii_from_fixed,
- (png_const_structrp png_ptr,
- png_charp ascii, size_t size, png_fixed_point fp),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);
#endif /* FIXED_POINT */
#endif /* sCAL */
@@ -2133,7 +1726,7 @@ PNG_INTERNAL_FUNCTION(void, png_ascii_from_fixed,
*/
#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */
-/* Result codes for the parser (boolean - true means ok, false means
+/* Result codes for the parser (boolean - true meants ok, false means
* not ok yet.)
*/
#define PNG_FP_MAYBE 0 /* The number may be valid in the future */
@@ -2168,9 +1761,8 @@ PNG_INTERNAL_FUNCTION(void, png_ascii_from_fixed,
* that omits the last character (i.e. set the size to the index of
* the problem character.) This has not been tested within libpng.
*/
-PNG_INTERNAL_FUNCTION(int, png_check_fp_number,
- (png_const_charp string, size_t size, int *statep, size_t *whereami),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+ png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
/* This is the same but it checks a complete string and returns true
* only if it just contains a floating point number. As of 1.5.4 this
@@ -2178,61 +1770,52 @@ PNG_INTERNAL_FUNCTION(int, png_check_fp_number,
* it was valid (otherwise it returns 0.) This can be used for testing
* for negative or zero values using the sticky flag.
*/
-PNG_INTERNAL_FUNCTION(int, png_check_fp_string,
- (png_const_charp string, size_t size),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+ png_size_t size),PNG_EMPTY);
#endif /* pCAL || sCAL */
#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
- defined(PNG_COLORSPACE_SUPPORTED) ||\
- defined(PNG_INCH_CONVERSIONS_SUPPORTED) ||\
- defined(PNG_READ_pHYs_SUPPORTED)
+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
/* Added at libpng version 1.5.0 */
/* This is a utility to provide a*times/div (rounded) and indicate
* if there is an overflow. The result is a boolean - false (0)
* for overflow, true (1) if no overflow, in which case *res
* holds the result.
*/
-PNG_INTERNAL_FUNCTION(int, png_muldiv,
- (png_fixed_point_p res, png_fixed_point a,
- png_int_32 multiplied_by, png_int_32 divided_by),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
+ png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* Same deal, but issue a warning on overflow and return 0. */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,
+ (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,
+ png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED
/* Calculate a reciprocal - used for gamma values. This returns
* 0 if the argument is 0 in order to maintain an undefined value;
* there are no warnings.
*/
-PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal,
- (png_fixed_point a),
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
PNG_EMPTY);
-#endif
#ifdef PNG_READ_GAMMA_SUPPORTED
/* The same but gives a reciprocal of the product of two fixed point
* values. Accuracy is suitable for gamma calculations but this is
* not exact - use png_muldiv for that. Only required at present on read.
*/
-PNG_INTERNAL_FUNCTION(png_fixed_point, png_reciprocal2,
- (png_fixed_point a, png_fixed_point b),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
+ png_fixed_point b),PNG_EMPTY);
+#endif
/* Return true if the gamma value is significantly different from 1.0 */
-PNG_INTERNAL_FUNCTION(int, png_gamma_significant,
- (png_fixed_point gamma_value),
- PNG_EMPTY);
-
-/* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour
- * space information.
- *
- * NOTE: this uses precisely those chunks that libpng supports. For example it
- * doesn't use iCCP and it can only use cICP for known and manageable
- * transforms. For this reason a gamma specified by png_set_gamma always takes
- * precedence.
- */
-PNG_INTERNAL_FUNCTION(png_fixed_point, png_resolve_file_gamma,
- (png_const_structrp png_ptr),
+PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
PNG_EMPTY);
+#endif
+#ifdef PNG_READ_GAMMA_SUPPORTED
/* Internal fixed point gamma correction. These APIs are called as
* required to convert single values - they don't need to be fast,
* they are not used when processing image pixel values.
@@ -2240,45 +1823,21 @@ PNG_INTERNAL_FUNCTION(png_fixed_point, png_resolve_file_gamma,
* While the input is an 'unsigned' value it must actually be the
* correct bit value - 0..255 or 0..65535 as required.
*/
-PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_correct,
- (png_structrp png_ptr, unsigned int value, png_fixed_point gamma_value),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(png_uint_16, png_gamma_16bit_correct,
- (unsigned int value, png_fixed_point gamma_value),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(png_byte, png_gamma_8bit_correct,
- (unsigned int value, png_fixed_point gamma_value),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_destroy_gamma_table,
- (png_structrp png_ptr),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void, png_build_gamma_table,
- (png_structrp png_ptr, int bit_depth),
- PNG_EMPTY);
-#endif /* READ_GAMMA */
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
-/* Set the RGB coefficients if not already set by png_set_rgb_to_gray */
-PNG_INTERNAL_FUNCTION(void, png_set_rgb_coefficients,
- (png_structrp png_ptr),
- PNG_EMPTY);
-#endif
-
-#if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
-PNG_INTERNAL_FUNCTION(int, png_XYZ_from_xy,
- (png_XYZ *XYZ, const png_xy *xy),
- PNG_EMPTY);
-#endif /* cHRM || READ_RGB_TO_GRAY */
-
-#ifdef PNG_COLORSPACE_SUPPORTED
-PNG_INTERNAL_FUNCTION(int, png_xy_from_XYZ,
- (png_xy *xy, const png_XYZ *XYZ),
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
+ unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
+ int bit_depth),PNG_EMPTY);
#endif
/* SIMPLIFIED READ/WRITE SUPPORT */
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
- defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
/* The internal structure that png_image::opaque points to. */
typedef struct png_control
{
@@ -2287,7 +1846,7 @@ typedef struct png_control
png_voidp error_buf; /* Always a jmp_buf at present. */
png_const_bytep memory; /* Memory buffer. */
- size_t size; /* Size of the memory buffer. */
+ png_size_t size; /* Size of the memory buffer. */
unsigned int for_write :1; /* Otherwise it is a read structure */
unsigned int owned_file :1; /* We own the file in io_ptr */
@@ -2306,115 +1865,40 @@ typedef struct png_control
* errors that might occur. Returns true on success, false on failure (either
* of the function or as a result of a png_error.)
*/
-PNG_INTERNAL_CALLBACK(void, png_safe_error,
- (png_structp png_ptr, png_const_charp error_message),
- PNG_NORETURN);
+PNG_INTERNAL_FUNCTION(void,png_safe_error,(png_structp png_ptr,
+ png_const_charp error_message),PNG_NORETURN);
#ifdef PNG_WARNINGS_SUPPORTED
-PNG_INTERNAL_CALLBACK(void, png_safe_warning,
- (png_structp png_ptr, png_const_charp warning_message),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_safe_warning,(png_structp png_ptr,
+ png_const_charp warning_message),PNG_EMPTY);
#else
# define png_safe_warning 0/*dummy argument*/
#endif
-PNG_INTERNAL_FUNCTION(int, png_safe_execute,
- (png_imagep image, int (*function)(png_voidp), png_voidp arg),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
+ int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
/* Utility to log an error; this also cleans up the png_image; the function
* always returns 0 (false).
*/
-PNG_INTERNAL_FUNCTION(int, png_image_error,
- (png_imagep image, png_const_charp error_message),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
+ png_const_charp error_message),PNG_EMPTY);
#ifndef PNG_SIMPLIFIED_READ_SUPPORTED
/* png_image_free is used by the write code but not exported */
-PNG_INTERNAL_FUNCTION(void, png_image_free,
- (png_imagep image),
- PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
#endif /* !SIMPLIFIED_READ */
#endif /* SIMPLIFIED READ/WRITE */
-/* These are initialization functions for hardware specific PNG filter
- * optimizations; list these here then select the appropriate one at compile
- * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined
- * the generic code is used.
- */
#ifdef PNG_FILTER_OPTIMIZATIONS
-PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
- /* Just declare the optimization that will be used */
-#else
- /* List *all* the possible optimizations here - this branch is required if
- * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
- * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
+PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+ unsigned int bpp), PNG_EMPTY);
+ /* This is the initialization function for hardware specific optimizations,
+ * one implementation (for ARM NEON machines) is contained in
+ * arm/filter_neon.c. It need not be defined - the generic code will be used
+ * if not.
*/
-# if PNG_ARM_NEON_OPT > 0
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-#endif
-
-#if PNG_MIPS_MSA_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-#endif
-
-# if PNG_MIPS_MMI_IMPLEMENTATION > 0
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-# endif
-
-# if PNG_INTEL_SSE_IMPLEMENTATION > 0
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-# endif
-#endif
-
-#if PNG_LOONGARCH_LSX_OPT > 0
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-#endif
-
-# if PNG_RISCV_RVV_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_rvv,
- (png_structp png_ptr, unsigned int bpp),
- PNG_EMPTY);
-#endif
-
-PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword,
- (png_structrp png_ptr, png_const_charp key, png_bytep new_key),
- PNG_EMPTY);
-
-#if PNG_ARM_NEON_IMPLEMENTATION == 1
-PNG_INTERNAL_FUNCTION(void,
- png_riffle_palette_neon,
- (png_structrp),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(int,
- png_do_expand_palette_rgba8_neon,
- (png_structrp,
- png_row_infop,
- png_const_bytep,
- const png_bytepp,
- const png_bytepp),
- PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(int,
- png_do_expand_palette_rgb8_neon,
- (png_structrp,
- png_row_infop,
- png_const_bytep,
- const png_bytepp,
- const png_bytepp),
- PNG_EMPTY);
#endif
/* Maintainer: Put new private prototypes here ^ */
@@ -2426,3 +1910,4 @@ PNG_INTERNAL_FUNCTION(int,
#endif
#endif /* PNG_VERSION_INFO_ONLY */
+#endif /* PNGPRIV_H */
diff --git a/Windows_Libs/Dev/Render/libpng/pngread.c b/Windows_Libs/Dev/Render/libpng/pngread.c
index af2f44c..0a00439 100644
--- a/Windows_Libs/Dev/Render/libpng/pngread.c
+++ b/Windows_Libs/Dev/Render/libpng/pngread.c
@@ -1,9 +1,10 @@
+
/* pngread.c - read a PNG file
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -23,15 +24,14 @@
/* Create a PNG structure for reading, and allocate any memory needed. */
PNG_FUNCTION(png_structp,PNGAPI
png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn),
- PNG_ALLOCATED)
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
{
#ifndef PNG_USER_MEM_SUPPORTED
png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, NULL, NULL, NULL);
+ error_fn, warn_fn, NULL, NULL, NULL);
#else
return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
- warn_fn, NULL, NULL, NULL);
+ warn_fn, NULL, NULL, NULL);
}
/* Alternate create PNG structure for reading, and allocate any memory
@@ -40,12 +40,11 @@ png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
PNG_FUNCTION(png_structp,PNGAPI
png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED)
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{
png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
-#endif /* USER_MEM */
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr != NULL)
{
@@ -64,7 +63,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
/* In stable builds only warn if an application error can be completely
* handled.
*/
-# if PNG_RELEASE_BUILD
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
# endif
# endif
@@ -114,30 +113,30 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
*/
if (chunk_name == png_IDAT)
{
- if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_chunk_error(png_ptr, "Missing IHDR before IDAT");
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ !(png_ptr->mode & PNG_HAVE_PLTE))
png_chunk_error(png_ptr, "Missing PLTE before IDAT");
- else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+ else if (png_ptr->mode & PNG_AFTER_IDAT)
png_chunk_benign_error(png_ptr, "Too many IDATs found");
png_ptr->mode |= PNG_HAVE_IDAT;
}
- else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- {
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
png_ptr->mode |= PNG_AFTER_IDAT;
- }
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
if (chunk_name == png_IHDR)
- png_handle_chunk(png_ptr, info_ptr, length);
+ png_handle_IHDR(png_ptr, info_ptr, length);
else if (chunk_name == png_IEND)
- png_handle_chunk(png_ptr, info_ptr, length);
+ png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
@@ -154,6 +153,8 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
}
}
#endif
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
else if (chunk_name == png_IDAT)
{
@@ -161,11 +162,97 @@ png_read_info(png_structrp png_ptr, png_inforp info_ptr)
break;
}
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
else
- png_handle_chunk(png_ptr, info_ptr, length);
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
}
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
/* Optional call to update the users info_ptr structure */
void PNGAPI
@@ -189,7 +276,7 @@ png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
/* New in 1.6.0 this avoids the bug of doing the initializations twice */
else
png_app_error(png_ptr,
- "png_read_update_info/png_start_read_image: duplicate call");
+ "png_read_update_info/png_start_read_image: duplicate call");
}
}
@@ -212,78 +299,12 @@ png_start_read_image(png_structrp png_ptr)
/* New in 1.6.0 this avoids the bug of doing the initializations twice */
else
png_app_error(png_ptr,
- "png_start_read_image/png_read_update_info: duplicate call");
+ "png_start_read_image/png_read_update_info: duplicate call");
}
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Undoes intrapixel differencing,
- * NOTE: this is apparently only supported in the 'sequential' reader.
- */
-static void
-png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_read_intrapixel");
-
- if (
- (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
-
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
-
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
-
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
- *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
-
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
-
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
- png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
- png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
- png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
- png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
- *(rp ) = (png_byte)((red >> 8) & 0xff);
- *(rp + 1) = (png_byte)(red & 0xff);
- *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
- *(rp + 5) = (png_byte)(blue & 0xff);
- }
- }
- }
-}
-#endif /* MNG_FEATURES */
-
void PNGAPI
png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
{
@@ -298,7 +319,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
/* png_read_start_row sets the information (in particular iwidth) for this
* interlace pass.
*/
- if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
/* 1.5.6: row_info moved out of png_struct to a local here. */
@@ -309,47 +330,45 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
row_info.pixel_depth = png_ptr->pixel_depth;
row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
-#ifdef PNG_WARNINGS_SUPPORTED
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
/* Check for transforms that have been set but were defined out */
#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
- if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
- if ((png_ptr->transformations & PNG_FILLER) != 0)
+ if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
!defined(PNG_READ_PACKSWAP_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ if (png_ptr->transformations & PNG_PACKSWAP)
png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) != 0)
+ if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
- if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
- if ((png_ptr->transformations & PNG_BGR) != 0)
+ if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
- if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
#endif
}
-#endif /* WARNINGS */
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* If interlaced and we do not need a new row, combine row and return.
@@ -358,8 +377,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
* untransformed) and, because of the libpng API for interlaced images, this
* means we must transform before de-interlacing.
*/
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0)
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{
switch (png_ptr->pass)
{
@@ -430,7 +448,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
default:
case 6:
- if ((png_ptr->row_number & 1) == 0)
+ if (!(png_ptr->row_number & 1))
{
png_read_finish_row(png_ptr);
return;
@@ -440,18 +458,17 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
}
#endif
- if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "Invalid attempt to read row data");
/* Fill the row with IDAT data: */
- png_ptr->row_buf[0]=255; /* to force error if no data was found */
png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
{
if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
- png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
else
png_error(png_ptr, "bad adaptive filter value");
}
@@ -464,7 +481,7 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
#ifdef PNG_MNG_FEATURES_SUPPORTED
- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
{
/* Intrapixel differencing */
@@ -472,12 +489,9 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
}
#endif
+
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
- if (png_ptr->transformations
-# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
- || png_ptr->num_palette_max >= 0
-# endif
- )
+ if (png_ptr->transformations)
png_do_read_transformations(png_ptr, &row_info);
#endif
@@ -493,13 +507,13 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
png_error(png_ptr, "internal sequential row size calculation error");
#ifdef PNG_READ_INTERLACING_SUPPORTED
- /* Expand interlaced rows to full size */
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0)
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced &&
+ (png_ptr->transformations & PNG_INTERLACE))
{
if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
- png_ptr->transformations);
+ png_ptr->transformations);
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, 1/*display*/);
@@ -521,8 +535,9 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
if (png_ptr->read_row_fn != NULL)
(*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read one or more rows of image data. If the image is interlaced,
@@ -589,7 +604,7 @@ png_read_rows(png_structrp png_ptr, png_bytepp row,
dp++;
}
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read the entire image. If the image has an alpha channel or a tRNS
@@ -617,7 +632,7 @@ png_read_image(png_structrp png_ptr, png_bytepp image)
return;
#ifdef PNG_READ_INTERLACING_SUPPORTED
- if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
{
pass = png_set_interlace_handling(png_ptr);
/* And make sure transforms are initialized. */
@@ -625,15 +640,14 @@ png_read_image(png_structrp png_ptr, png_bytepp image)
}
else
{
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) == 0)
+ if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
{
/* Caller called png_start_read_image or png_read_update_info without
* first turning on the PNG_INTERLACE transform. We can fix this here,
* but the caller should do it!
*/
png_warning(png_ptr, "Interlace handling should be turned on when "
- "using png_read_image");
+ "using png_read_image");
/* Make sure this is set correctly */
png_ptr->num_rows = png_ptr->height;
}
@@ -663,7 +677,7 @@ png_read_image(png_structrp png_ptr, png_bytepp image)
}
}
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
/* Read the end of the PNG file. Will not read past the end of the
@@ -686,15 +700,15 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
* still be pending IDAT data and an owned zstream. Deal with this here.
*/
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
- if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)
+ if (!png_chunk_unknown_handling(png_ptr, png_IDAT))
#endif
png_read_finish_IDAT(png_ptr);
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Report invalid palette index; added at libng-1.5.10 */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- png_ptr->num_palette_max >= png_ptr->num_palette)
- png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+ png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Read palette index exceeding num_palette");
#endif
do
@@ -702,31 +716,19 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
png_uint_32 length = png_read_chunk_header(png_ptr);
png_uint_32 chunk_name = png_ptr->chunk_name;
- if (chunk_name != png_IDAT)
- {
- /* These flags must be set consistently for all non-IDAT chunks,
- * including the unknown chunks.
- */
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT;
- }
+ if (chunk_name == png_IHDR)
+ png_handle_IHDR(png_ptr, info_ptr, length);
- if (chunk_name == png_IEND)
- png_handle_chunk(png_ptr, info_ptr, length);
-
- else if (chunk_name == png_IHDR)
- png_handle_chunk(png_ptr, info_ptr, length);
-
- else if (info_ptr == NULL)
- png_crc_finish(png_ptr, length);
+ else if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
{
if (chunk_name == png_IDAT)
{
- if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
- || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
- png_benign_error(png_ptr, ".Too many IDATs found");
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_benign_error(png_ptr, "Too many IDATs found");
}
png_handle_unknown(png_ptr, info_ptr, length, keep);
if (chunk_name == png_PLTE)
@@ -737,23 +739,107 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
else if (chunk_name == png_IDAT)
{
/* Zero length IDATs are legal after the last IDAT has been
- * read, but not after other chunks have been read. 1.6 does not
- * always read all the deflate data; specifically it cannot be relied
- * upon to read the Adler32 at the end. If it doesn't ignore IDAT
- * chunks which are longer than zero as well:
+ * read, but not after other chunks have been read.
*/
- if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
- || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
- png_benign_error(png_ptr, "..Too many IDATs found");
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_benign_error(png_ptr, "Too many IDATs found");
png_crc_finish(png_ptr, length);
}
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
else
- png_handle_chunk(png_ptr, info_ptr, length);
- } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ } while (!(png_ptr->mode & PNG_HAVE_IEND));
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
/* Free all memory used in the read struct */
static void
@@ -766,33 +852,22 @@ png_read_destroy(png_structrp png_ptr)
#endif
png_free(png_ptr, png_ptr->big_row_buf);
- png_ptr->big_row_buf = NULL;
png_free(png_ptr, png_ptr->big_prev_row);
- png_ptr->big_prev_row = NULL;
png_free(png_ptr, png_ptr->read_buffer);
- png_ptr->read_buffer = NULL;
#ifdef PNG_READ_QUANTIZE_SUPPORTED
png_free(png_ptr, png_ptr->palette_lookup);
- png_ptr->palette_lookup = NULL;
png_free(png_ptr, png_ptr->quantize_index);
- png_ptr->quantize_index = NULL;
#endif
- if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
- {
+ if (png_ptr->free_me & PNG_FREE_PLTE)
png_zfree(png_ptr, png_ptr->palette);
- png_ptr->palette = NULL;
- }
png_ptr->free_me &= ~PNG_FREE_PLTE;
#if defined(PNG_tRNS_SUPPORTED) || \
defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
- if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
- {
+ if (png_ptr->free_me & PNG_FREE_TRNS)
png_free(png_ptr, png_ptr->trans_alpha);
- png_ptr->trans_alpha = NULL;
- }
png_ptr->free_me &= ~PNG_FREE_TRNS;
#endif
@@ -800,25 +875,15 @@ png_read_destroy(png_structrp png_ptr)
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
png_free(png_ptr, png_ptr->save_buffer);
- png_ptr->save_buffer = NULL;
#endif
-#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) &&\
defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
png_free(png_ptr, png_ptr->unknown_chunk.data);
- png_ptr->unknown_chunk.data = NULL;
#endif
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list = NULL;
-#endif
-
-#if defined(PNG_READ_EXPAND_SUPPORTED) && \
- (defined(PNG_ARM_NEON_IMPLEMENTATION) || \
- defined(PNG_RISCV_RVV_IMPLEMENTATION))
- png_free(png_ptr, png_ptr->riffled_palette);
- png_ptr->riffled_palette = NULL;
#endif
/* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
@@ -868,9 +933,10 @@ png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
#ifdef PNG_INFO_IMAGE_SUPPORTED
void PNGAPI
png_read_png(png_structrp png_ptr, png_inforp info_ptr,
- int transforms, png_voidp params)
+ int transforms,
+ voidp params)
{
- png_debug(1, "in png_read_png");
+ int row;
if (png_ptr == NULL || info_ptr == NULL)
return;
@@ -883,149 +949,127 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
png_error(png_ptr, "Image is too high to process with png_read_png()");
/* -------------- image transformations start here ------------------- */
- /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
- * is not implemented. This will only happen in de-configured (non-default)
- * libpng builds. The results can be unexpected - png_read_png may return
- * short or mal-formed rows because the transform is skipped.
- */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
/* Tell libpng to strip 16-bit/color files down to 8 bits per color.
*/
- if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)
- /* Added at libpng-1.5.4. "strip_16" produces the same result that it
- * did in earlier versions, while "scale_16" is now more accurate.
- */
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if (transforms & PNG_TRANSFORM_SCALE_16)
+ {
+ /* Added at libpng-1.5.4. "strip_16" produces the same result that it
+ * did in earlier versions, while "scale_16" is now more accurate.
+ */
png_set_scale_16(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
+ }
#endif
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
/* If both SCALE and STRIP are required pngrtran will effectively cancel the
* latter by doing SCALE first. This is ok and allows apps not to check for
* which is supported to get the right answer.
*/
- if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ if (transforms & PNG_TRANSFORM_STRIP_16)
png_set_strip_16(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
#endif
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
/* Strip alpha bytes from the input data without combining with
* the background (not recommended).
*/
- if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
png_set_strip_alpha(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
#endif
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
/* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
* byte into separate bytes (useful for paletted and grayscale images).
*/
- if ((transforms & PNG_TRANSFORM_PACKING) != 0)
-#ifdef PNG_READ_PACK_SUPPORTED
+ if (transforms & PNG_TRANSFORM_PACKING)
png_set_packing(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
#endif
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
/* Change the order of packed pixels to least significant bit first
* (not useful if you are using png_set_packing).
*/
- if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
png_set_packswap(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
#endif
+#ifdef PNG_READ_EXPAND_SUPPORTED
/* Expand paletted colors into true RGB triplets
* Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
* Expand paletted or RGB images with transparency to full alpha
* channels so the data will be available as RGBA quartets.
*/
- if ((transforms & PNG_TRANSFORM_EXPAND) != 0)
-#ifdef PNG_READ_EXPAND_SUPPORTED
- png_set_expand(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
+ if (transforms & PNG_TRANSFORM_EXPAND)
+ if ((png_ptr->bit_depth < 8) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
#endif
/* We don't handle background color or gamma transformation or quantizing.
*/
+#ifdef PNG_READ_INVERT_SUPPORTED
/* Invert monochrome files to have 0 as white and 1 as black
*/
- if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
-#ifdef PNG_READ_INVERT_SUPPORTED
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
png_set_invert_mono(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
#endif
+#ifdef PNG_READ_SHIFT_SUPPORTED
/* If you want to shift the pixel values from the range [0,255] or
* [0,65535] to the original [0,7] or [0,31], or whatever range the
* colors were originally in:
*/
- if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
-#ifdef PNG_READ_SHIFT_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
- png_set_shift(png_ptr, &info_ptr->sig_bit);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ // 4j change: initialize with null to silence MSVC
+ png_color_8p sig_bit = NULL;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
#endif
- /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
- if ((transforms & PNG_TRANSFORM_BGR) != 0)
#ifdef PNG_READ_BGR_SUPPORTED
+ /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+ if (transforms & PNG_TRANSFORM_BGR)
png_set_bgr(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
#endif
- /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
- if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
png_set_swap_alpha(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
#endif
- /* Swap bytes of 16-bit files to least significant byte first */
- if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
#ifdef PNG_READ_SWAP_SUPPORTED
+ /* Swap bytes of 16-bit files to least significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
png_set_swap(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
#endif
/* Added at libpng-1.2.41 */
- /* Invert the alpha channel from opacity to transparency */
- if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
png_set_invert_alpha(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
#endif
/* Added at libpng-1.2.41 */
- /* Expand grayscale image to RGB */
- if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* Expand grayscale image to RGB */
+ if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
png_set_gray_to_rgb(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
#endif
/* Added at libpng-1.5.4 */
- if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)
#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if (transforms & PNG_TRANSFORM_EXPAND_16)
png_set_expand_16(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
#endif
/* We don't handle adding filler bytes */
@@ -1048,17 +1092,16 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
{
png_uint_32 iptr;
- info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
- info_ptr->height * (sizeof (png_bytep))));
-
+ info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+ info_ptr->height * (sizeof (png_bytep)));
for (iptr=0; iptrheight; iptr++)
info_ptr->row_pointers[iptr] = NULL;
info_ptr->free_me |= PNG_FREE_ROWS;
- for (iptr = 0; iptr < info_ptr->height; iptr++)
- info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
- png_malloc(png_ptr, info_ptr->rowbytes));
+ for (row = 0; row < (int)info_ptr->height; row++)
+ info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr));
}
png_read_image(png_ptr, info_ptr->row_pointers);
@@ -1067,10 +1110,12 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr);
+ PNG_UNUSED(transforms) /* Quiet compiler warnings */
PNG_UNUSED(params)
+
}
-#endif /* INFO_IMAGE */
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
/* SIMPLIFIED READ
@@ -1081,14 +1126,15 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
/* Arguments to png_image_finish_read: */
/* Encoding of PNG data (used by the color-map code) */
-# define P_NOTSET 0 /* File encoding not yet known */
-# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */
-# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
-# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */
-# define P_LINEAR8 4 /* 8-bit linear: only from a file value */
+/* TODO: change these, dang, ANSI-C reserves the 'E' namespace. */
+# define E_NOTSET 0 /* File encoding not yet known */
+# define E_sRGB 1 /* 8-bit encoded to sRGB gamma */
+# define E_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
+# define E_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */
+# define E_LINEAR8 4 /* 8-bit linear: only from a file value */
/* Color-map processing: after libpng has run on the PNG image further
- * processing may be needed to convert the data to color-map indices.
+ * processing may be needed to conver the data to color-map indicies.
*/
#define PNG_CMAP_NONE 0
#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */
@@ -1105,20 +1151,19 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
typedef struct
{
- /* Arguments */
+ /* Arguments: */
png_imagep image;
- png_voidp buffer;
+ png_voidp buffer;
png_int_32 row_stride;
- png_voidp colormap;
+ png_voidp colormap;
png_const_colorp background;
-
- /* Instance variables */
- png_voidp local_row;
- png_voidp first_row;
- ptrdiff_t row_step; /* step between rows */
- int file_encoding; /* E_ values above */
- png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */
- int colormap_processing; /* PNG_CMAP_ values above */
+ /* Local variables: */
+ png_voidp local_row;
+ png_voidp first_row;
+ ptrdiff_t row_bytes; /* step between rows */
+ int file_encoding; /* E_ values above */
+ png_fixed_point gamma_to_linear; /* For E_FILE, reciprocal of gamma */
+ int colormap_processing; /* PNG_CMAP_ values above */
} png_image_read_control;
/* Do all the *safe* initialization - 'safe' means that png_error won't be
@@ -1147,7 +1192,7 @@ png_image_read_init(png_imagep image)
if (info_ptr != NULL)
{
png_controlp control = png_voidcast(png_controlp,
- png_malloc_warn(png_ptr, (sizeof *control)));
+ png_malloc_warn(png_ptr, (sizeof *control)));
if (control != NULL)
{
@@ -1180,10 +1225,10 @@ png_image_format(png_structrp png_ptr)
{
png_uint_32 format = 0;
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
format |= PNG_FORMAT_FLAG_COLOR;
- if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)
format |= PNG_FORMAT_FLAG_ALPHA;
/* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
@@ -1197,37 +1242,12 @@ png_image_format(png_structrp png_ptr)
if (png_ptr->bit_depth == 16)
format |= PNG_FORMAT_FLAG_LINEAR;
- if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)
+ if (png_ptr->color_type & PNG_COLOR_MASK_PALETTE)
format |= PNG_FORMAT_FLAG_COLORMAP;
return format;
}
-static int
-chromaticities_match_sRGB(const png_xy *xy)
-{
-# define sRGB_TOLERANCE 1000
- static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
- {
- /* color x y */
- /* red */ 64000, 33000,
- /* green */ 30000, 60000,
- /* blue */ 15000, 6000,
- /* white */ 31270, 32900
- };
-
- if (PNG_OUT_OF_RANGE(xy->whitex, sRGB_xy.whitex,sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->whitey, sRGB_xy.whitey,sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->redx, sRGB_xy.redx, sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->redy, sRGB_xy.redy, sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->greenx, sRGB_xy.greenx,sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->greeny, sRGB_xy.greeny,sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->bluex, sRGB_xy.bluex, sRGB_TOLERANCE) ||
- PNG_OUT_OF_RANGE(xy->bluey, sRGB_xy.bluey, sRGB_TOLERANCE))
- return 0;
- return 1;
-}
-
/* Is the given gamma significantly different from sRGB? The test is the same
* one used in pngrtran.c when deciding whether to do gamma correction. The
* arithmetic optimizes the division by using the fact that the inverse of the
@@ -1236,44 +1256,22 @@ chromaticities_match_sRGB(const png_xy *xy)
static int
png_gamma_not_sRGB(png_fixed_point g)
{
- /* 1.6.47: use the same sanity checks as used in pngrtran.c */
- if (g < PNG_LIB_GAMMA_MIN || g > PNG_LIB_GAMMA_MAX)
- return 0; /* Includes the uninitialized value 0 */
+ if (g < PNG_FP_1)
+ {
+ /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
+ if (g == 0)
+ return 0;
- return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
+ return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
+ }
+
+ return 1;
}
/* Do the main body of a 'png_image_begin_read' function; read the PNG file
* header and fill in all the information. This is executed in a safe context,
* unlike the init routine above.
*/
-static int
-png_image_is_not_sRGB(png_const_structrp png_ptr)
-{
- /* Does the colorspace **not** match sRGB? The flag is only set if the
- * answer can be determined reliably.
- *
- * png_struct::chromaticities always exists since the simplified API
- * requires rgb-to-gray. The mDCV, cICP and cHRM chunks may all set it to
- * a non-sRGB value, so it needs to be checked but **only** if one of
- * those chunks occured in the file.
- */
- /* Highest priority: check to be safe. */
- if (png_has_chunk(png_ptr, cICP) || png_has_chunk(png_ptr, mDCV))
- return !chromaticities_match_sRGB(&png_ptr->chromaticities);
-
- /* If the image is marked as sRGB then it is... */
- if (png_has_chunk(png_ptr, sRGB))
- return 0;
-
- /* Last stop: cHRM, must check: */
- if (png_has_chunk(png_ptr, cHRM))
- return !chromaticities_match_sRGB(&png_ptr->chromaticities);
-
- /* Else default to sRGB */
- return 0;
-}
-
static int
png_image_read_header(png_voidp argument)
{
@@ -1281,9 +1279,7 @@ png_image_read_header(png_voidp argument)
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
png_set_benign_errors(png_ptr, 1/*warn*/);
-#endif
png_read_info(png_ptr, info_ptr);
/* Do this the fast way; just read directly out of png_struct. */
@@ -1295,13 +1291,17 @@ png_image_read_header(png_voidp argument)
image->format = format;
- /* Greyscale images don't (typically) have colour space information and
- * using it is pretty much impossible, so use sRGB for grayscale (it
- * doesn't matter r==g==b so the transform is irrelevant.)
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Does the colorspace match sRGB? If there is no color endpoint
+ * (colorant) information assume yes, otherwise require the
+ * 'ENDPOINTS_MATCHE_sRGB' colorspace flag to have been set. If the
+ * colorspace has been determined to be invalid ignore it.
*/
- if ((format & PNG_FORMAT_FLAG_COLOR) != 0 &&
- png_image_is_not_sRGB(png_ptr))
+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
+ & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
+ PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
+#endif
}
/* We need the maximum number of entries regardless of the format the
@@ -1317,7 +1317,7 @@ png_image_read_header(png_voidp argument)
break;
case PNG_COLOR_TYPE_PALETTE:
- cmap_entries = (png_uint_32)png_ptr->num_palette;
+ cmap_entries = png_ptr->num_palette;
break;
default:
@@ -1336,13 +1336,13 @@ png_image_read_header(png_voidp argument)
#ifdef PNG_STDIO_SUPPORTED
int PNGAPI
-png_image_begin_read_from_stdio(png_imagep image, FILE *file)
+png_image_begin_read_from_stdio(png_imagep image, FILE* file)
{
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
if (file != NULL)
{
- if (png_image_read_init(image) != 0)
+ if (png_image_read_init(image))
{
/* This is slightly evil, but png_init_io doesn't do anything other
* than this and we haven't changed the standard IO functions so
@@ -1355,12 +1355,12 @@ png_image_begin_read_from_stdio(png_imagep image, FILE *file)
else
return png_image_error(image,
- "png_image_begin_read_from_stdio: invalid argument");
+ "png_image_begin_read_from_stdio: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
return 0;
}
@@ -1376,7 +1376,7 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name)
if (fp != NULL)
{
- if (png_image_read_init(image) != 0)
+ if (png_image_read_init(image))
{
image->opaque->png_ptr->io_ptr = fp;
image->opaque->owned_file = 1;
@@ -1393,19 +1393,19 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name)
else
return png_image_error(image,
- "png_image_begin_read_from_file: invalid argument");
+ "png_image_begin_read_from_file: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
return 0;
}
-#endif /* STDIO */
+#endif /* PNG_STDIO_SUPPORTED */
static void PNGCBAPI
-png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need)
+png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
{
if (png_ptr != NULL)
{
@@ -1416,7 +1416,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need)
if (cp != NULL)
{
png_const_bytep memory = cp->memory;
- size_t size = cp->size;
+ png_size_t size = cp->size;
if (memory != NULL && size >= need)
{
@@ -1435,13 +1435,13 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need)
}
int PNGAPI png_image_begin_read_from_memory(png_imagep image,
- png_const_voidp memory, size_t size)
+ png_const_voidp memory, png_size_t size)
{
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
if (memory != NULL && size > 0)
{
- if (png_image_read_init(image) != 0)
+ if (png_image_read_init(image))
{
/* Now set the IO functions to read from the memory buffer and
* store it into io_ptr. Again do this in-place to avoid calling a
@@ -1458,12 +1458,12 @@ int PNGAPI png_image_begin_read_from_memory(png_imagep image,
else
return png_image_error(image,
- "png_image_begin_read_from_memory: invalid argument");
+ "png_image_begin_read_from_memory: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
return 0;
}
@@ -1483,41 +1483,37 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
*
* Or image data handling:
*
- * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
+ * tRNS, bKGD, gAMA, cHRM, sRGB, iCCP and sBIT.
*
* This provides a small performance improvement and eliminates any
* potential vulnerability to security problems in the unused chunks.
- *
- * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
- * too. This allows the simplified API to be compiled without iCCP support.
*/
{
- static const png_byte chunks_to_process[] = {
+ static PNG_CONST png_byte chunks_to_process[] = {
98, 75, 71, 68, '\0', /* bKGD */
99, 72, 82, 77, '\0', /* cHRM */
- 99, 73, 67, 80, '\0', /* cICP */
103, 65, 77, 65, '\0', /* gAMA */
- 109, 68, 67, 86, '\0', /* mDCV */
+ 105, 67, 67, 80, '\0', /* iCCP */
115, 66, 73, 84, '\0', /* sBIT */
115, 82, 71, 66, '\0', /* sRGB */
- };
+ };
/* Ignore unknown chunks and all other chunks except for the
* IHDR, PLTE, tRNS, IDAT, and IEND chunks.
*/
png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
- NULL, -1);
+ NULL, -1);
/* But do not ignore image data handling chunks */
png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
- chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
- }
+ chunks_to_process, (sizeof chunks_to_process)/5);
+ }
}
# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
#else
# define PNG_SKIP_CHUNKS(p) ((void)0)
-#endif /* HANDLE_AS_UNKNOWN */
+#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
/* The following macro gives the exact rounded answer for all values in the
* range 0..255 (it actually divides by 51.2, but the rounding still generates
@@ -1529,38 +1525,30 @@ png_image_skip_unused_chunks(png_structrp png_ptr)
static void
set_file_encoding(png_image_read_control *display)
{
- png_structrp png_ptr = display->image->opaque->png_ptr;
- png_fixed_point g = png_resolve_file_gamma(png_ptr);
-
- /* PNGv3: the result may be 0 however the 'default_gamma' should have been
- * set before this is called so zero is an error:
- */
- if (g == 0)
- png_error(png_ptr, "internal: default gamma not set");
-
- if (png_gamma_significant(g) != 0)
+ png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
+ if (png_gamma_significant(g))
{
- if (png_gamma_not_sRGB(g) != 0)
+ if (png_gamma_not_sRGB(g))
{
- display->file_encoding = P_FILE;
+ display->file_encoding = E_FILE;
display->gamma_to_linear = png_reciprocal(g);
}
else
- display->file_encoding = P_sRGB;
+ display->file_encoding = E_sRGB;
}
else
- display->file_encoding = P_LINEAR8;
+ display->file_encoding = E_LINEAR8;
}
static unsigned int
decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
{
- if (encoding == P_FILE) /* double check */
+ if (encoding == E_FILE) /* double check */
encoding = display->file_encoding;
- if (encoding == P_NOTSET) /* must be the file encoding */
+ if (encoding == E_NOTSET) /* must be the file encoding */
{
set_file_encoding(display);
encoding = display->file_encoding;
@@ -1568,26 +1556,25 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
switch (encoding)
{
- case P_FILE:
+ case E_FILE:
value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
break;
- case P_sRGB:
+ case E_sRGB:
value = png_sRGB_table[value];
break;
- case P_LINEAR:
+ case E_LINEAR:
break;
- case P_LINEAR8:
+ case E_LINEAR8:
value *= 257;
break;
-#ifdef __GNUC__
default:
png_error(display->image->opaque->png_ptr,
- "unexpected encoding (internal error)");
-#endif
+ "unexpected encoding (internal error)");
+ break;
}
return value;
@@ -1595,13 +1582,13 @@ decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
static png_uint_32
png_colormap_compose(png_image_read_control *display,
- png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
- png_uint_32 background, int encoding)
+ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+ png_uint_32 background, int encoding)
{
/* The file value is composed on the background, the background has the given
- * encoding and so does the result, the file is encoded with P_FILE and the
+ * encoding and so does the result, the file is encoded with E_FILE and the
* file and alpha are 8-bit values. The (output) encoding will always be
- * P_LINEAR or P_sRGB.
+ * E_LINEAR or E_sRGB.
*/
png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
png_uint_32 b = decode_gamma(display, background, encoding);
@@ -1611,7 +1598,7 @@ png_colormap_compose(png_image_read_control *display,
*/
f = f * alpha + b * (255-alpha);
- if (encoding == P_LINEAR)
+ if (encoding == E_LINEAR)
{
/* Scale to 65535; divide by 255, approximately (in fact this is extremely
* accurate, it divides by 255.00000005937181414556, with no overflow.)
@@ -1621,25 +1608,25 @@ png_colormap_compose(png_image_read_control *display,
f = (f+32768) >> 16;
}
- else /* P_sRGB */
+ else /* E_sRGB */
f = PNG_sRGB_FROM_LINEAR(f);
return f;
}
-/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
+/* NOTE: E_LINEAR values to this routine must be 16-bit, but E_FILE values must
* be 8-bit.
*/
static void
png_create_colormap_entry(png_image_read_control *display,
- png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
- png_uint_32 alpha, int encoding)
+ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+ png_uint_32 alpha, int encoding)
{
png_imagep image = display->image;
- int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
- P_LINEAR : P_sRGB;
- int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
- (red != green || green != blue);
+ const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ?
+ E_LINEAR : E_sRGB;
+ const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
+ (red != green || green != blue);
if (ip > 255)
png_error(image->opaque->png_ptr, "color-map index out of range");
@@ -1647,18 +1634,18 @@ png_create_colormap_entry(png_image_read_control *display,
/* Update the cache with whether the file gamma is significantly different
* from sRGB.
*/
- if (encoding == P_FILE)
+ if (encoding == E_FILE)
{
- if (display->file_encoding == P_NOTSET)
+ if (display->file_encoding == E_NOTSET)
set_file_encoding(display);
- /* Note that the cached value may be P_FILE too, but if it is then the
+ /* Note that the cached value may be E_FILE too, but if it is then the
* gamma_to_linear member has been set.
*/
encoding = display->file_encoding;
}
- if (encoding == P_FILE)
+ if (encoding == E_FILE)
{
png_fixed_point g = display->gamma_to_linear;
@@ -1666,10 +1653,10 @@ png_create_colormap_entry(png_image_read_control *display,
green = png_gamma_16bit_correct(green*257, g);
blue = png_gamma_16bit_correct(blue*257, g);
- if (convert_to_Y != 0 || output_encoding == P_LINEAR)
+ if (convert_to_Y || output_encoding == E_LINEAR)
{
alpha *= 257;
- encoding = P_LINEAR;
+ encoding = E_LINEAR;
}
else
@@ -1677,11 +1664,11 @@ png_create_colormap_entry(png_image_read_control *display,
red = PNG_sRGB_FROM_LINEAR(red * 255);
green = PNG_sRGB_FROM_LINEAR(green * 255);
blue = PNG_sRGB_FROM_LINEAR(blue * 255);
- encoding = P_sRGB;
+ encoding = E_sRGB;
}
}
- else if (encoding == P_LINEAR8)
+ else if (encoding == E_LINEAR8)
{
/* This encoding occurs quite frequently in test cases because PngSuite
* includes a gAMA 1.0 chunk with most images.
@@ -1690,11 +1677,10 @@ png_create_colormap_entry(png_image_read_control *display,
green *= 257;
blue *= 257;
alpha *= 257;
- encoding = P_LINEAR;
+ encoding = E_LINEAR;
}
- else if (encoding == P_sRGB &&
- (convert_to_Y != 0 || output_encoding == P_LINEAR))
+ else if (encoding == E_sRGB && (convert_to_Y || output_encoding == E_LINEAR))
{
/* The values are 8-bit sRGB values, but must be converted to 16-bit
* linear.
@@ -1703,19 +1689,19 @@ png_create_colormap_entry(png_image_read_control *display,
green = png_sRGB_table[green];
blue = png_sRGB_table[blue];
alpha *= 257;
- encoding = P_LINEAR;
+ encoding = E_LINEAR;
}
/* This is set if the color isn't gray but the output is. */
- if (encoding == P_LINEAR)
+ if (encoding == E_LINEAR)
{
- if (convert_to_Y != 0)
+ if (convert_to_Y)
{
/* NOTE: these values are copied from png_do_rgb_to_gray */
png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green +
(png_uint_32)2366 * blue;
- if (output_encoding == P_LINEAR)
+ if (output_encoding == E_LINEAR)
y = (y + 16384) >> 15;
else
@@ -1724,20 +1710,19 @@ png_create_colormap_entry(png_image_read_control *display,
y = (y + 128) >> 8;
y *= 255;
y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
- alpha = PNG_DIV257(alpha);
- encoding = P_sRGB;
+ encoding = E_sRGB;
}
blue = red = green = y;
}
- else if (output_encoding == P_sRGB)
+ else if (output_encoding == E_sRGB)
{
red = PNG_sRGB_FROM_LINEAR(red * 255);
green = PNG_sRGB_FROM_LINEAR(green * 255);
blue = PNG_sRGB_FROM_LINEAR(blue * 255);
alpha = PNG_DIV257(alpha);
- encoding = P_sRGB;
+ encoding = E_sRGB;
}
}
@@ -1746,19 +1731,19 @@ png_create_colormap_entry(png_image_read_control *display,
/* Store the value. */
{
-# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
(image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
# else
# define afirst 0
# endif
# ifdef PNG_FORMAT_BGR_SUPPORTED
- int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+ const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
# else
# define bgr 0
# endif
- if (output_encoding == P_LINEAR)
+ if (output_encoding == E_LINEAR)
{
png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
@@ -1772,7 +1757,7 @@ png_create_colormap_entry(png_image_read_control *display,
{
case 4:
entry[afirst ? 0 : 3] = (png_uint_16)alpha;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case 3:
if (alpha < 65535)
@@ -1794,7 +1779,7 @@ png_create_colormap_entry(png_image_read_control *display,
case 2:
entry[1 ^ afirst] = (png_uint_16)alpha;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case 1:
if (alpha < 65535)
@@ -1813,7 +1798,7 @@ png_create_colormap_entry(png_image_read_control *display,
}
}
- else /* output encoding is P_sRGB */
+ else /* output encoding is E_sRGB */
{
png_bytep entry = png_voidcast(png_bytep, display->colormap);
@@ -1823,7 +1808,6 @@ png_create_colormap_entry(png_image_read_control *display,
{
case 4:
entry[afirst ? 0 : 3] = (png_byte)alpha;
- /* FALLTHROUGH */
case 3:
entry[afirst + (2 ^ bgr)] = (png_byte)blue;
entry[afirst + 1] = (png_byte)green;
@@ -1832,7 +1816,6 @@ png_create_colormap_entry(png_image_read_control *display,
case 2:
entry[1 ^ afirst] = (png_byte)alpha;
- /* FALLTHROUGH */
case 1:
entry[afirst] = (png_byte)green;
break;
@@ -1857,9 +1840,9 @@ make_gray_file_colormap(png_image_read_control *display)
unsigned int i;
for (i=0; i<256; ++i)
- png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
+ png_create_colormap_entry(display, i, i, i, i, 255, E_FILE);
- return (int)i;
+ return i;
}
static int
@@ -1868,9 +1851,9 @@ make_gray_colormap(png_image_read_control *display)
unsigned int i;
for (i=0; i<256; ++i)
- png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
+ png_create_colormap_entry(display, i, i, i, i, 255, E_sRGB);
- return (int)i;
+ return i;
}
#define PNG_GRAY_COLORMAP_ENTRIES 256
@@ -1907,13 +1890,13 @@ make_ga_colormap(png_image_read_control *display)
while (i < 231)
{
unsigned int gray = (i * 256 + 115) / 231;
- png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
+ png_create_colormap_entry(display, i++, gray, gray, gray, 255, E_sRGB);
}
/* 255 is used here for the component values for consistency with the code
* that undoes premultiplication in pngwrite.c.
*/
- png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
+ png_create_colormap_entry(display, i++, 255, 255, 255, 0, E_sRGB);
for (a=1; a<5; ++a)
{
@@ -1921,10 +1904,10 @@ make_ga_colormap(png_image_read_control *display)
for (g=0; g<6; ++g)
png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
- P_sRGB);
+ E_sRGB);
}
- return (int)i;
+ return i;
}
#define PNG_GA_COLORMAP_ENTRIES 256
@@ -1945,11 +1928,11 @@ make_rgb_colormap(png_image_read_control *display)
for (b=0; b<6; ++b)
png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
- P_sRGB);
+ E_sRGB);
}
}
- return (int)i;
+ return i;
}
#define PNG_RGB_COLORMAP_ENTRIES 216
@@ -1963,16 +1946,16 @@ png_image_read_colormap(png_voidp argument)
{
png_image_read_control *display =
png_voidcast(png_image_read_control*, argument);
- png_imagep image = display->image;
+ const png_imagep image = display->image;
- png_structrp png_ptr = image->opaque->png_ptr;
- png_uint_32 output_format = image->format;
- int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
- P_LINEAR : P_sRGB;
+ const png_structrp png_ptr = image->opaque->png_ptr;
+ const png_uint_32 output_format = image->format;
+ const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ?
+ E_LINEAR : E_sRGB;
unsigned int cmap_entries;
unsigned int output_processing; /* Output processing option */
- unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
+ unsigned int data_encoding = E_NOTSET; /* Encoding libpng must produce */
/* Background information; the background color and the index of this color
* in the color-map if it exists (else 256).
@@ -1992,12 +1975,12 @@ png_image_read_colormap(png_voidp argument)
png_ptr->num_trans > 0) /* alpha in input */ &&
((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
{
- if (output_encoding == P_LINEAR) /* compose on black */
+ if (output_encoding == E_LINEAR) /* compose on black */
back_b = back_g = back_r = 0;
else if (display->background == NULL /* no way to remove it */)
png_error(png_ptr,
- "background color must be supplied to remove alpha/transparency");
+ "a background color must be supplied to remove alpha/transparency");
/* Get a copy of the background color (this avoids repeating the checks
* below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the
@@ -2006,7 +1989,7 @@ png_image_read_colormap(png_voidp argument)
else
{
back_g = display->background->green;
- if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)
+ if (output_format & PNG_FORMAT_FLAG_COLOR)
{
back_r = display->background->red;
back_b = display->background->blue;
@@ -2016,7 +1999,7 @@ png_image_read_colormap(png_voidp argument)
}
}
- else if (output_encoding == P_LINEAR)
+ else if (output_encoding == E_LINEAR)
back_b = back_r = back_g = 65535;
else
@@ -2025,18 +2008,24 @@ png_image_read_colormap(png_voidp argument)
/* Default the input file gamma if required - this is necessary because
* libpng assumes that if no gamma information is present the data is in the
* output format, but the simplified API deduces the gamma from the input
- * format. The 'default' gamma value is also set by png_set_alpha_mode, but
- * this is happening before any such call, so:
- *
- * TODO: should be an internal API and all this code should be copied into a
- * single common gamma+colorspace file.
+ * format.
*/
- if (png_ptr->bit_depth == 16 &&
- (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
- png_ptr->default_gamma = PNG_GAMMA_LINEAR;
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
+ {
+ /* Do this directly, not using the png_colorspace functions, to ensure
+ * that it happens even if the colorspace is invalid (though probably if
+ * it is the setting will be ignored) Note that the same thing can be
+ * achieved at the application interface with png_set_gAMA.
+ */
+ if (png_ptr->bit_depth == 16 &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
- else
- png_ptr->default_gamma = PNG_GAMMA_sRGB_INVERSE;
+ else
+ png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
/* Decide what to do based on the PNG color type of the input data. The
* utility function png_create_colormap_entry deals with most aspects of the
@@ -2068,7 +2057,7 @@ png_image_read_colormap(png_voidp argument)
trans = png_ptr->trans_color.gray;
if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
- back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+ back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
}
/* png_create_colormap_entry just takes an RGBA and writes the
@@ -2086,7 +2075,7 @@ png_image_read_colormap(png_voidp argument)
*/
if (i != trans)
png_create_colormap_entry(display, i, val, val, val, 255,
- P_FILE/*8-bit with file gamma*/);
+ E_FILE/*8-bit with file gamma*/);
/* Else this entry is transparent. The colors don't matter if
* there is an alpha channel (back_alpha == 0), but it does no
@@ -2098,14 +2087,14 @@ png_image_read_colormap(png_voidp argument)
*/
else
png_create_colormap_entry(display, i, back_r, back_g, back_b,
- back_alpha, output_encoding);
+ back_alpha, output_encoding);
}
/* We need libpng to preserve the original encoding. */
- data_encoding = P_FILE;
+ data_encoding = E_FILE;
/* The rows from libpng, while technically gray values, are now also
- * color-map indices; however, they may need to be expanded to 1
+ * color-map indicies; however, they may need to be expanded to 1
* byte per pixel. This is what png_set_packing does (i.e., it
* unpacks the bit values into bytes.)
*/
@@ -2131,18 +2120,18 @@ png_image_read_colormap(png_voidp argument)
* ensuring that the corresponding gray level matches the background
* color exactly.
*/
- data_encoding = P_sRGB;
+ data_encoding = E_sRGB;
if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
png_error(png_ptr, "gray[16] color-map: too few entries");
- cmap_entries = (unsigned int)make_gray_colormap(display);
+ cmap_entries = make_gray_colormap(display);
if (png_ptr->num_trans > 0)
{
unsigned int back_alpha;
- if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
back_alpha = 0;
else
@@ -2155,7 +2144,7 @@ png_image_read_colormap(png_voidp argument)
png_color_16 c;
png_uint_32 gray = back_g;
- if (output_encoding == P_LINEAR)
+ if (output_encoding == E_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
@@ -2163,7 +2152,7 @@ png_image_read_colormap(png_voidp argument)
* matches.
*/
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 65535, P_LINEAR);
+ back_g, 65535, E_LINEAR);
}
/* The background passed to libpng, however, must be the
@@ -2177,28 +2166,22 @@ png_image_read_colormap(png_voidp argument)
* doesn't.
*/
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_NONE;
break;
}
-#ifdef __COVERITY__
- /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
- * here.
- */
- back_alpha = 255;
-#else
- back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
-#endif
+
+ back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
}
/* output_processing means that the libpng-processed row will be
* 8-bit GA and it has to be processing to single byte color-map
* values. Entry 254 is replaced by either a completely
* transparent entry or by the background color at full
- * precision (and the background color is not a simple gray
- * level in this case.)
+ * precision (and the background color is not a simple gray leve
+ * in this case.)
*/
expand_tRNS = 1;
output_processing = PNG_CMAP_TRANS;
@@ -2208,7 +2191,7 @@ png_image_read_colormap(png_voidp argument)
* background color at full precision.
*/
png_create_colormap_entry(display, 254, back_r, back_g, back_b,
- back_alpha, output_encoding);
+ back_alpha, output_encoding);
}
else
@@ -2227,14 +2210,14 @@ png_image_read_colormap(png_voidp argument)
* worry about tRNS matching - tRNS is ignored if there is an alpha
* channel.
*/
- data_encoding = P_sRGB;
+ data_encoding = E_sRGB;
- if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
{
if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
png_error(png_ptr, "gray+alpha color-map: too few entries");
- cmap_entries = (unsigned int)make_ga_colormap(display);
+ cmap_entries = make_ga_colormap(display);
background_index = PNG_CMAP_GA_BACKGROUND;
output_processing = PNG_CMAP_GA;
@@ -2268,15 +2251,15 @@ png_image_read_colormap(png_voidp argument)
if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
png_error(png_ptr, "gray-alpha color-map: too few entries");
- cmap_entries = (unsigned int)make_gray_colormap(display);
+ cmap_entries = make_gray_colormap(display);
- if (output_encoding == P_LINEAR)
+ if (output_encoding == E_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
/* And make sure the corresponding palette entry matches. */
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 65535, P_LINEAR);
+ back_g, 65535, E_LINEAR);
}
/* The background passed to libpng, however, must be the sRGB
@@ -2286,8 +2269,8 @@ png_image_read_colormap(png_voidp argument)
c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_NONE;
}
@@ -2307,7 +2290,7 @@ png_image_read_colormap(png_voidp argument)
{
png_uint_32 gray = (i * 256 + 115) / 231;
png_create_colormap_entry(display, i++, gray, gray, gray,
- 255, P_sRGB);
+ 255, E_sRGB);
}
/* NOTE: this preserves the full precision of the application
@@ -2315,14 +2298,7 @@ png_image_read_colormap(png_voidp argument)
*/
background_index = i;
png_create_colormap_entry(display, i++, back_r, back_g, back_b,
-#ifdef __COVERITY__
- /* Coverity claims that output_encoding
- * cannot be 2 (P_LINEAR) here.
- */ 255U,
-#else
- output_encoding == P_LINEAR ? 65535U : 255U,
-#endif
- output_encoding);
+ output_encoding == E_LINEAR ? 65535U : 255U, output_encoding);
/* For non-opaque input composite on the sRGB background - this
* requires inverting the encoding for each component. The input
@@ -2332,7 +2308,7 @@ png_image_read_colormap(png_voidp argument)
* represents. Consequently 'G' is always sRGB encoded, while
* 'A' is linear. We need the linear background colors.
*/
- if (output_encoding == P_sRGB) /* else already linear */
+ if (output_encoding == E_sRGB) /* else already linear */
{
/* This may produce a value not exactly matching the
* background, but that's ok because these numbers are only
@@ -2360,9 +2336,9 @@ png_image_read_colormap(png_voidp argument)
png_uint_32 gray = png_sRGB_table[g*51] * alpha;
png_create_colormap_entry(display, i++,
- PNG_sRGB_FROM_LINEAR(gray + back_rx),
- PNG_sRGB_FROM_LINEAR(gray + back_gx),
- PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+ PNG_sRGB_FROM_LINEAR(gray + back_rx),
+ PNG_sRGB_FROM_LINEAR(gray + back_gx),
+ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, E_sRGB);
}
}
@@ -2388,8 +2364,8 @@ png_image_read_colormap(png_voidp argument)
* png_set_tRNS_to_alpha before png_set_background_fixed.
*/
png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
- -1);
- data_encoding = P_sRGB;
+ -1);
+ data_encoding = E_sRGB;
/* The output will now be one or two 8-bit gray or gray+alpha
* channels. The more complex case arises when the input has alpha.
@@ -2407,15 +2383,13 @@ png_image_read_colormap(png_voidp argument)
if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
png_error(png_ptr, "rgb[ga] color-map: too few entries");
- cmap_entries = (unsigned int)make_ga_colormap(display);
+ cmap_entries = make_ga_colormap(display);
background_index = PNG_CMAP_GA_BACKGROUND;
output_processing = PNG_CMAP_GA;
}
else
{
- const png_fixed_point gamma = png_resolve_file_gamma(png_ptr);
-
/* Either the input or the output has no alpha channel, so there
* will be no non-opaque pixels in the color-map; it will just be
* grayscale.
@@ -2430,20 +2404,17 @@ png_image_read_colormap(png_voidp argument)
* this case and doing it in the palette; this will result in
* duplicate palette entries, but that's better than the
* alternative of double gamma correction.
- *
- * NOTE: PNGv3: check the resolved result of all the potentially
- * different colour space chunks.
*/
if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->num_trans > 0) &&
- png_gamma_not_sRGB(gamma) != 0)
+ png_gamma_not_sRGB(png_ptr->colorspace.gamma))
{
- cmap_entries = (unsigned int)make_gray_file_colormap(display);
- data_encoding = P_FILE;
+ cmap_entries = make_gray_file_colormap(display);
+ data_encoding = E_FILE;
}
else
- cmap_entries = (unsigned int)make_gray_colormap(display);
+ cmap_entries = make_gray_colormap(display);
/* But if the input has alpha or transparency it must be removed
*/
@@ -2458,34 +2429,34 @@ png_image_read_colormap(png_voidp argument)
* it. Achieve this simply by ensuring that the entry
* selected for the background really is the background color.
*/
- if (data_encoding == P_FILE) /* from the fixup above */
+ if (data_encoding == E_FILE) /* from the fixup above */
{
/* The app supplied a gray which is in output_encoding, we
- * need to convert it to a value of the input (P_FILE)
+ * need to convert it to a value of the input (E_FILE)
* encoding then set this palette entry to the required
* output encoding.
*/
- if (output_encoding == P_sRGB)
- gray = png_sRGB_table[gray]; /* now P_LINEAR */
+ if (output_encoding == E_sRGB)
+ gray = png_sRGB_table[gray]; /* now E_LINEAR */
- gray = PNG_DIV257(png_gamma_16bit_correct(gray, gamma));
- /* now P_FILE */
+ gray = PNG_DIV257(png_gamma_16bit_correct(gray,
+ png_ptr->colorspace.gamma)); /* now E_FILE */
/* And make sure the corresponding palette entry contains
* exactly the required sRGB value.
*/
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 0/*unused*/, output_encoding);
+ back_g, 0/*unused*/, output_encoding);
}
- else if (output_encoding == P_LINEAR)
+ else if (output_encoding == E_LINEAR)
{
gray = PNG_sRGB_FROM_LINEAR(gray * 255);
/* And make sure the corresponding palette entry matches.
*/
png_create_colormap_entry(display, gray, back_g, back_g,
- back_g, 0/*unused*/, P_LINEAR);
+ back_g, 0/*unused*/, E_LINEAR);
}
/* The background passed to libpng, however, must be the
@@ -2500,8 +2471,8 @@ png_image_read_colormap(png_voidp argument)
*/
expand_tRNS = 1;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
}
output_processing = PNG_CMAP_NONE;
@@ -2515,7 +2486,7 @@ png_image_read_colormap(png_voidp argument)
* to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
* Consequently we always want libpng to produce sRGB data.
*/
- data_encoding = P_sRGB;
+ data_encoding = E_sRGB;
/* Is there any transparency or alpha? */
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
@@ -2524,18 +2495,18 @@ png_image_read_colormap(png_voidp argument)
/* Is there alpha in the output too? If so all four channels are
* processed into a special RGB cube with alpha support.
*/
- if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
{
png_uint_32 r;
if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
png_error(png_ptr, "rgb+alpha color-map: too few entries");
- cmap_entries = (unsigned int)make_rgb_colormap(display);
+ cmap_entries = make_rgb_colormap(display);
/* Add a transparent entry. */
png_create_colormap_entry(display, cmap_entries, 255, 255,
- 255, 0, P_sRGB);
+ 255, 0, E_sRGB);
/* This is stored as the background index for the processing
* algorithm.
@@ -2556,7 +2527,7 @@ png_image_read_colormap(png_voidp argument)
*/
for (b=0; b<256; b = (b << 1) | 0x7f)
png_create_colormap_entry(display, cmap_entries++,
- r, g, b, 128, P_sRGB);
+ r, g, b, 128, E_sRGB);
}
}
@@ -2580,12 +2551,12 @@ png_image_read_colormap(png_voidp argument)
if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
png_error(png_ptr, "rgb-alpha color-map: too few entries");
- cmap_entries = (unsigned int)make_rgb_colormap(display);
+ cmap_entries = make_rgb_colormap(display);
png_create_colormap_entry(display, cmap_entries, back_r,
- back_g, back_b, 0/*unused*/, output_encoding);
+ back_g, back_b, 0/*unused*/, output_encoding);
- if (output_encoding == P_LINEAR)
+ if (output_encoding == E_LINEAR)
{
r = PNG_sRGB_FROM_LINEAR(back_r * 255);
g = PNG_sRGB_FROM_LINEAR(back_g * 255);
@@ -2605,9 +2576,9 @@ png_image_read_colormap(png_voidp argument)
* index.
*/
if (memcmp((png_const_bytep)display->colormap +
- sample_size * cmap_entries,
- (png_const_bytep)display->colormap +
- sample_size * PNG_RGB_INDEX(r,g,b),
+ sample_size * cmap_entries,
+ (png_const_bytep)display->colormap +
+ sample_size * PNG_RGB_INDEX(r,g,b),
sample_size) != 0)
{
/* The background color must be added. */
@@ -2625,13 +2596,13 @@ png_image_read_colormap(png_voidp argument)
*/
for (b=0; b<256; b = (b << 1) | 0x7f)
png_create_colormap_entry(display, cmap_entries++,
- png_colormap_compose(display, r, P_sRGB, 128,
- back_r, output_encoding),
- png_colormap_compose(display, g, P_sRGB, 128,
- back_g, output_encoding),
- png_colormap_compose(display, b, P_sRGB, 128,
- back_b, output_encoding),
- 0/*unused*/, output_encoding);
+ png_colormap_compose(display, r, E_sRGB, 128,
+ back_r, output_encoding),
+ png_colormap_compose(display, g, E_sRGB, 128,
+ back_g, output_encoding),
+ png_colormap_compose(display, b, E_sRGB, 128,
+ back_b, output_encoding),
+ 0/*unused*/, output_encoding);
}
}
@@ -2649,8 +2620,8 @@ png_image_read_colormap(png_voidp argument)
c.blue = (png_uint_16)back_b;
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
output_processing = PNG_CMAP_RGB;
}
@@ -2665,7 +2636,7 @@ png_image_read_colormap(png_voidp argument)
if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
png_error(png_ptr, "rgb color-map: too few entries");
- cmap_entries = (unsigned int)make_rgb_colormap(display);
+ cmap_entries = make_rgb_colormap(display);
output_processing = PNG_CMAP_RGB;
}
}
@@ -2679,7 +2650,7 @@ png_image_read_colormap(png_voidp argument)
unsigned int num_trans = png_ptr->num_trans;
png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
png_const_colorp colormap = png_ptr->palette;
- int do_background = trans != NULL &&
+ const int do_background = trans != NULL &&
(output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
unsigned int i;
@@ -2688,21 +2659,21 @@ png_image_read_colormap(png_voidp argument)
num_trans = 0;
output_processing = PNG_CMAP_NONE;
- data_encoding = P_FILE; /* Don't change from color-map indices */
- cmap_entries = (unsigned int)png_ptr->num_palette;
+ data_encoding = E_FILE; /* Don't change from color-map indicies */
+ cmap_entries = png_ptr->num_palette;
if (cmap_entries > 256)
cmap_entries = 256;
- if (cmap_entries > (unsigned int)image->colormap_entries)
+ if (cmap_entries > image->colormap_entries)
png_error(png_ptr, "palette color-map: too few entries");
for (i=0; i < cmap_entries; ++i)
{
- if (do_background != 0 && i < num_trans && trans[i] < 255)
+ if (do_background && i < num_trans && trans[i] < 255)
{
if (trans[i] == 0)
png_create_colormap_entry(display, i, back_r, back_g,
- back_b, 0, output_encoding);
+ back_b, 0, output_encoding);
else
{
@@ -2710,25 +2681,25 @@ png_image_read_colormap(png_voidp argument)
* on the sRGB color in 'back'.
*/
png_create_colormap_entry(display, i,
- png_colormap_compose(display, colormap[i].red,
- P_FILE, trans[i], back_r, output_encoding),
- png_colormap_compose(display, colormap[i].green,
- P_FILE, trans[i], back_g, output_encoding),
- png_colormap_compose(display, colormap[i].blue,
- P_FILE, trans[i], back_b, output_encoding),
- output_encoding == P_LINEAR ? trans[i] * 257U :
- trans[i],
- output_encoding);
+ png_colormap_compose(display, colormap[i].red, E_FILE,
+ trans[i], back_r, output_encoding),
+ png_colormap_compose(display, colormap[i].green, E_FILE,
+ trans[i], back_g, output_encoding),
+ png_colormap_compose(display, colormap[i].blue, E_FILE,
+ trans[i], back_b, output_encoding),
+ output_encoding == E_LINEAR ? trans[i] * 257U :
+ trans[i],
+ output_encoding);
}
}
else
png_create_colormap_entry(display, i, colormap[i].red,
- colormap[i].green, colormap[i].blue,
- i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+ colormap[i].green, colormap[i].blue,
+ i < num_trans ? trans[i] : 255U, E_FILE/*8-bit*/);
}
- /* The PNG data may have indices packed in fewer than 8 bits, it
+ /* The PNG data may have indicies packed in fewer than 8 bits, it
* must be expanded if so.
*/
if (png_ptr->bit_depth < 8)
@@ -2739,29 +2710,29 @@ png_image_read_colormap(png_voidp argument)
default:
png_error(png_ptr, "invalid PNG color type");
/*NOT REACHED*/
+ break;
}
/* Now deal with the output processing */
- if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
+ if (expand_tRNS && png_ptr->num_trans > 0 &&
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
png_set_tRNS_to_alpha(png_ptr);
switch (data_encoding)
{
- case P_sRGB:
+ default:
+ png_error(png_ptr, "bad data option (internal error)");
+ break;
+
+ case E_sRGB:
/* Change to 8-bit sRGB */
png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
- /* FALLTHROUGH */
+ /* FALL THROUGH */
- case P_FILE:
+ case E_FILE:
if (png_ptr->bit_depth > 8)
png_set_scale_16(png_ptr);
break;
-
-#ifdef __GNUC__
- default:
- png_error(png_ptr, "bad data option (internal error)");
-#endif
}
if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
@@ -2805,7 +2776,7 @@ png_image_read_colormap(png_voidp argument)
png_error(png_ptr, "bad background index (internal error)");
}
- display->colormap_processing = (int)output_processing;
+ display->colormap_processing = output_processing;
return 1/*ok*/;
}
@@ -2815,7 +2786,7 @@ static int
png_image_read_and_map(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
int passes;
@@ -2835,21 +2806,22 @@ png_image_read_and_map(png_voidp argument)
break;
default:
+ passes = 0;
png_error(png_ptr, "unknown interlace type");
}
{
- png_uint_32 height = image->height;
- png_uint_32 width = image->width;
- int proc = display->colormap_processing;
- png_bytep first_row = png_voidcast(png_bytep, display->first_row);
- ptrdiff_t row_step = display->row_step;
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ int proc = display->colormap_processing;
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t step_row = display->row_bytes;
int pass;
for (pass = 0; pass < passes; ++pass)
{
- unsigned int startx, stepx, stepy;
- png_uint_32 y;
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
{
@@ -2873,7 +2845,7 @@ png_image_read_and_map(png_voidp argument)
for (; ylocal_row);
- png_bytep outrow = first_row + y * row_step;
+ png_bytep outrow = first_row + y * step_row;
png_const_bytep end_row = outrow + width;
/* Read read the libpng data into the temporary buffer. */
@@ -2952,7 +2924,7 @@ png_image_read_and_map(png_voidp argument)
if (alpha >= 196)
*outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
- inrow[2]);
+ inrow[2]);
else if (alpha < 64)
*outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
@@ -3004,7 +2976,7 @@ static int
png_image_read_colormapped(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_controlp control = image->opaque;
png_structrp png_ptr = control->png_ptr;
@@ -3069,7 +3041,8 @@ png_image_read_colormapped(png_voidp argument)
image->colormap_entries == 244 /* 216 + 1 + 27 */)
break;
- goto bad_output;
+ /* goto bad_output; */
+ /* FALL THROUGH */
default:
bad_output:
@@ -3082,20 +3055,20 @@ png_image_read_colormapped(png_voidp argument)
*/
{
png_voidp first_row = display->buffer;
- ptrdiff_t row_step = display->row_stride;
+ ptrdiff_t row_bytes = display->row_stride;
- /* The following adjustment is to ensure that calculations are correct,
- * regardless whether row_step is positive or negative.
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
*/
- if (row_step < 0)
+ if (row_bytes < 0)
{
char *ptr = png_voidcast(char*, first_row);
- ptr += (image->height-1) * (-row_step);
+ ptr += (image->height-1) * (-row_bytes);
first_row = png_voidcast(png_voidp, ptr);
}
display->first_row = first_row;
- display->row_step = row_step;
+ display->row_bytes = row_bytes;
}
if (passes == 0)
@@ -3113,17 +3086,17 @@ png_image_read_colormapped(png_voidp argument)
else
{
- ptrdiff_t row_step = display->row_step;
+ png_alloc_size_t row_bytes = display->row_bytes;
while (--passes >= 0)
{
- png_uint_32 y = image->height;
- png_bytep row = png_voidcast(png_bytep, display->first_row);
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_read_row(png_ptr, row, NULL);
- row += row_step;
+ row += row_bytes;
}
}
@@ -3131,67 +3104,12 @@ png_image_read_colormapped(png_voidp argument)
}
}
-/* Row reading for interlaced 16-to-8 bit depth conversion with local buffer. */
-static int
-png_image_read_direct_scaled(png_voidp argument)
-{
- png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
- png_imagep image = display->image;
- png_structrp png_ptr = image->opaque->png_ptr;
- png_inforp info_ptr = image->opaque->info_ptr;
- png_bytep local_row = png_voidcast(png_bytep, display->local_row);
- png_bytep first_row = png_voidcast(png_bytep, display->first_row);
- ptrdiff_t row_step = display->row_step;
- size_t row_bytes = png_get_rowbytes(png_ptr, info_ptr);
- int passes;
-
- /* Handle interlacing. */
- switch (png_ptr->interlaced)
- {
- case PNG_INTERLACE_NONE:
- passes = 1;
- break;
-
- case PNG_INTERLACE_ADAM7:
- passes = PNG_INTERLACE_ADAM7_PASSES;
- break;
-
- default:
- png_error(png_ptr, "unknown interlace type");
- }
-
- /* Read each pass using local_row as intermediate buffer. */
- while (--passes >= 0)
- {
- png_uint_32 y = image->height;
- png_bytep output_row = first_row;
-
- for (; y > 0; --y)
- {
- /* Read into local_row (gets transformed 8-bit data). */
- png_read_row(png_ptr, local_row, NULL);
-
- /* Copy from local_row to user buffer.
- * Use row_bytes (i.e. the actual size in bytes of the row data) for
- * copying into output_row. Use row_step for advancing output_row,
- * to respect the caller's stride for padding or negative (bottom-up)
- * layouts.
- */
- memcpy(output_row, local_row, row_bytes);
- output_row += row_step;
- }
- }
-
- return 1;
-}
-
/* Just the row reading part of png_image_read. */
static int
png_image_read_composite(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
int passes;
@@ -3207,22 +3125,21 @@ png_image_read_composite(png_voidp argument)
break;
default:
+ passes = 0;
png_error(png_ptr, "unknown interlace type");
}
{
- png_uint_32 height = image->height;
- png_uint_32 width = image->width;
- ptrdiff_t row_step = display->row_step;
- unsigned int channels =
- (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
- int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ ptrdiff_t step_row = display->row_bytes;
+ unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
int pass;
for (pass = 0; pass < passes; ++pass)
{
- unsigned int startx, stepx, stepy;
- png_uint_32 y;
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
{
@@ -3254,7 +3171,7 @@ png_image_read_composite(png_voidp argument)
png_read_row(png_ptr, inrow, NULL);
outrow = png_voidcast(png_bytep, display->first_row);
- outrow += y * row_step;
+ outrow += y * step_row;
end_row = outrow + width * channels;
/* Now do the composition on each pixel in this row. */
@@ -3273,44 +3190,20 @@ png_image_read_composite(png_voidp argument)
if (alpha < 255) /* else just use component */
{
- if (optimize_alpha != 0)
- {
- /* This is PNG_OPTIMIZED_ALPHA, the component value
- * is a linear 8-bit value. Combine this with the
- * current outrow[c] value which is sRGB encoded.
- * Arithmetic here is 16-bits to preserve the output
- * values correctly.
- */
- component *= 257*255; /* =65535 */
- component += (255-alpha)*png_sRGB_table[outrow[c]];
+ /* This is PNG_OPTIMIZED_ALPHA, the component value
+ * is a linear 8-bit value. Combine this with the
+ * current outrow[c] value which is sRGB encoded.
+ * Arithmetic here is 16-bits to preserve the output
+ * values correctly.
+ */
+ component *= 257*255; /* =65535 */
+ component += (255-alpha)*png_sRGB_table[outrow[c]];
- /* Clamp to the valid range to defend against
- * unforeseen cases where the data might be sRGB
- * instead of linear premultiplied.
- * (Belt-and-suspenders for CVE-2025-66293.)
- */
- if (component > 255*65535)
- component = 255*65535;
-
- /* So 'component' is scaled by 255*65535 and is
- * therefore appropriate for the sRGB-to-linear
- * conversion table.
- */
- component = PNG_sRGB_FROM_LINEAR(component);
- }
- else
- {
- /* Compositing was already done on the palette
- * entries. The data is sRGB premultiplied on black.
- * Composite with the background in sRGB space.
- * This is not gamma-correct, but matches what was
- * done to the palette.
- */
- png_uint_32 background = outrow[c];
- component += ((255-alpha) * background + 127) / 255;
- if (component > 255)
- component = 255;
- }
+ /* So 'component' is scaled by 255*65535 and is
+ * therefore appropriate for the sRGB to linear
+ * conversion table.
+ */
+ component = PNG_sRGB_FROM_LINEAR(component);
}
outrow[c] = (png_byte)component;
@@ -3333,17 +3226,17 @@ png_image_read_composite(png_voidp argument)
* PNG_COMPOSITE
* PNG_GAMMA
*
- * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and
+ * This is a work-round for the fact that both the PNG_RGB_TO_GRAY and
* PNG_COMPOSITE code performs gamma correction, so we get double gamma
- * correction. The fix-up is to prevent the PNG_COMPOSITE operation from
- * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha
- * row and handles the removal or pre-multiplication of the alpha channel.
+ * correction. The fix-up is to prevent the PNG_COMPOSITE operation happening
+ * inside libpng, so this routine sees an 8 or 16-bit gray+alpha row and handles
+ * the removal or pre-multiplication of the alpha channel.
*/
static int
png_image_read_background(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
@@ -3381,30 +3274,32 @@ png_image_read_background(png_voidp argument)
break;
default:
+ passes = 0;
png_error(png_ptr, "unknown interlace type");
}
- /* Use direct access to info_ptr here because otherwise the simplified API
- * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is
- * checking the value after libpng expansions, not the original value in the
- * PNG.
- */
- switch (info_ptr->bit_depth)
+ switch (png_get_bit_depth(png_ptr, info_ptr))
{
+ default:
+ png_error(png_ptr, "unexpected bit depth");
+ break;
+
case 8:
/* 8-bit sRGB gray values with an alpha channel; the alpha channel is
- * to be removed by composing on a background: either the row if
+ * to be removed by composing on a backgroundi: either the row if
* display->background is NULL or display->background->green if not.
* Unlike the code above ALPHA_OPTIMIZED has *not* been done.
*/
{
png_bytep first_row = png_voidcast(png_bytep, display->first_row);
- ptrdiff_t row_step = display->row_step;
+ ptrdiff_t step_row = display->row_bytes;
for (pass = 0; pass < passes; ++pass)
{
- unsigned int startx, stepx, stepy;
- png_uint_32 y;
+ png_bytep row = png_voidcast(png_bytep,
+ display->first_row);
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
{
@@ -3430,8 +3325,8 @@ png_image_read_background(png_voidp argument)
for (; ylocal_row);
- png_bytep outrow = first_row + y * row_step;
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
png_const_bytep end_row = outrow + width;
/* Read the row, which is packed: */
@@ -3475,8 +3370,8 @@ png_image_read_background(png_voidp argument)
for (; ylocal_row);
- png_bytep outrow = first_row + y * row_step;
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
png_const_bytep end_row = outrow + width;
/* Read the row, which is packed: */
@@ -3507,6 +3402,8 @@ png_image_read_background(png_voidp argument)
inrow += 2; /* gray and alpha channel */
}
+
+ row += display->row_bytes;
}
}
}
@@ -3520,26 +3417,22 @@ png_image_read_background(png_voidp argument)
*/
{
png_uint_16p first_row = png_voidcast(png_uint_16p,
- display->first_row);
+ display->first_row);
/* The division by two is safe because the caller passed in a
- * stride which was multiplied by 2 (below) to get row_step.
+ * stride which was multiplied by 2 (below) to get row_bytes.
*/
- ptrdiff_t row_step = display->row_step / 2;
- unsigned int preserve_alpha = (image->format &
- PNG_FORMAT_FLAG_ALPHA) != 0;
- unsigned int outchannels = 1U+preserve_alpha;
+ ptrdiff_t step_row = display->row_bytes / 2;
+ int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+ unsigned int outchannels = 1+preserve_alpha;
int swap_alpha = 0;
-# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
- if (preserve_alpha != 0 &&
- (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
- swap_alpha = 1;
-# endif
+ if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST))
+ swap_alpha = 1;
for (pass = 0; pass < passes; ++pass)
{
- unsigned int startx, stepx, stepy;
- png_uint_32 y;
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
/* The 'x' start and step are adjusted to output components here.
*/
@@ -3566,12 +3459,12 @@ png_image_read_background(png_voidp argument)
for (; ylocal_row), NULL);
+ display->local_row), NULL);
inrow = png_voidcast(png_const_uint_16p, display->local_row);
/* Now do the pre-multiplication on each pixel in this row.
@@ -3596,7 +3489,7 @@ png_image_read_background(png_voidp argument)
component = 0;
outrow[swap_alpha] = (png_uint_16)component;
- if (preserve_alpha != 0)
+ if (preserve_alpha)
outrow[1 ^ swap_alpha] = alpha;
inrow += 2; /* components and alpha channel */
@@ -3605,11 +3498,6 @@ png_image_read_background(png_voidp argument)
}
}
break;
-
-#ifdef __GNUC__
- default:
- png_error(png_ptr, "unexpected bit depth");
-#endif
}
return 1;
@@ -3620,7 +3508,7 @@ static int
png_image_read_direct(png_voidp argument)
{
png_image_read_control *display = png_voidcast(png_image_read_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
@@ -3629,7 +3517,6 @@ png_image_read_direct(png_voidp argument)
int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
int do_local_compose = 0;
int do_local_background = 0; /* to avoid double gamma correction bug */
- int do_local_scale = 0; /* for interlaced 16-to-8 bit conversion */
int passes = 0;
/* Add transforms to ensure the correct output format is produced then check
@@ -3647,10 +3534,10 @@ png_image_read_direct(png_voidp argument)
int mode; /* alpha mode */
/* Do this first so that we have a record if rgb to gray is happening. */
- if ((change & PNG_FORMAT_FLAG_COLOR) != 0)
+ if (change & PNG_FORMAT_FLAG_COLOR)
{
/* gray<->color transformation required. */
- if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+ if (format & PNG_FORMAT_FLAG_COLOR)
png_set_gray_to_rgb(png_ptr);
else
@@ -3668,11 +3555,11 @@ png_image_read_direct(png_voidp argument)
* enormous change) 'do_local_background' is used to indicate that
* the problem exists.
*/
- if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
do_local_background = 1/*maybe*/;
png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
- PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
}
change &= ~PNG_FORMAT_FLAG_COLOR;
@@ -3681,16 +3568,10 @@ png_image_read_direct(png_voidp argument)
/* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
*/
{
- /* This is safe but should no longer be necessary as
- * png_ptr->default_gamma should have been set after the
- * info-before-IDAT was read in png_image_read_header.
- *
- * TODO: 1.8: remove this and see what happens.
- */
png_fixed_point input_gamma_default;
- if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
- (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ if ((base_format & PNG_FORMAT_FLAG_LINEAR) &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
input_gamma_default = PNG_GAMMA_LINEAR;
else
input_gamma_default = PNG_DEFAULT_sRGB;
@@ -3701,12 +3582,12 @@ png_image_read_direct(png_voidp argument)
png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
}
- if (linear != 0)
+ if (linear)
{
/* If there *is* an alpha channel in the input it must be multiplied
* out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
*/
- if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
mode = PNG_ALPHA_STANDARD; /* associated alpha */
else
@@ -3721,19 +3602,13 @@ png_image_read_direct(png_voidp argument)
output_gamma = PNG_DEFAULT_sRGB;
}
- if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
- {
- mode = PNG_ALPHA_OPTIMIZED;
- change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
- }
-
/* If 'do_local_background' is set check for the presence of gamma
* correction; this is part of the work-round for the libpng bug
* described above.
*
* TODO: fix libpng and remove this.
*/
- if (do_local_background != 0)
+ if (do_local_background)
{
png_fixed_point gtest;
@@ -3742,9 +3617,8 @@ png_image_read_direct(png_voidp argument)
* yet; it's set below. png_struct::gamma, however, is set to the
* final value.
*/
- if (png_muldiv(>est, output_gamma,
- png_resolve_file_gamma(png_ptr), PNG_FP_1) != 0 &&
- png_gamma_significant(gtest) == 0)
+ if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma,
+ PNG_FP_1) && !png_gamma_significant(gtest))
do_local_background = 0;
else if (mode == PNG_ALPHA_STANDARD)
@@ -3757,44 +3631,36 @@ png_image_read_direct(png_voidp argument)
}
/* If the bit-depth changes then handle that here. */
- if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)
+ if (change & PNG_FORMAT_FLAG_LINEAR)
{
- if (linear != 0 /*16-bit output*/)
+ if (linear /*16-bit output*/)
png_set_expand_16(png_ptr);
else /* 8-bit output */
- {
png_set_scale_16(png_ptr);
- /* For interlaced images, use local_row buffer to avoid overflow
- * in png_combine_row() which writes using IHDR bit-depth.
- */
- if (png_ptr->interlaced != 0)
- do_local_scale = 1;
- }
-
change &= ~PNG_FORMAT_FLAG_LINEAR;
}
/* Now the background/alpha channel changes. */
- if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (change & PNG_FORMAT_FLAG_ALPHA)
{
/* Removing an alpha channel requires composition for the 8-bit
* formats; for the 16-bit it is already done, above, by the
* pre-multiplication and the channel just needs to be stripped.
*/
- if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
{
/* If RGB->gray is happening the alpha channel must be left and the
* operation completed locally.
*
* TODO: fix libpng and remove this.
*/
- if (do_local_background != 0)
+ if (do_local_background)
do_local_background = 2/*required*/;
/* 16-bit output: just remove the channel */
- else if (linear != 0) /* compose on black (well, pre-multiply) */
+ else if (linear) /* compose on black (well, pre-multiply) */
png_set_strip_alpha(png_ptr);
/* 8-bit output: do an appropriate compose */
@@ -3815,8 +3681,8 @@ png_image_read_direct(png_voidp argument)
* pixels.
*/
png_set_background_fixed(png_ptr, &c,
- PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
- 0/*gamma: not used*/);
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
}
else /* compose on row: implemented below. */
@@ -3841,22 +3707,22 @@ png_image_read_direct(png_voidp argument)
png_uint_32 filler; /* opaque filler */
int where;
- if (linear != 0)
+ if (linear)
filler = 65535;
else
filler = 255;
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
- {
- where = PNG_FILLER_BEFORE;
- change &= ~PNG_FORMAT_FLAG_AFIRST;
- }
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_AFIRST)
+ {
+ where = PNG_FILLER_BEFORE;
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
- else
-#endif
- where = PNG_FILLER_AFTER;
+ else
+# endif
+ where = PNG_FILLER_AFTER;
png_set_add_alpha(png_ptr, filler, where);
}
@@ -3872,12 +3738,12 @@ png_image_read_direct(png_voidp argument)
png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
# ifdef PNG_FORMAT_BGR_SUPPORTED
- if ((change & PNG_FORMAT_FLAG_BGR) != 0)
+ if (change & PNG_FORMAT_FLAG_BGR)
{
/* Check only the output format; PNG is never BGR; don't do this if
* the output is gray, but fix up the 'format' value in that case.
*/
- if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+ if (format & PNG_FORMAT_FLAG_COLOR)
png_set_bgr(png_ptr);
else
@@ -3888,14 +3754,14 @@ png_image_read_direct(png_voidp argument)
# endif
# ifdef PNG_FORMAT_AFIRST_SUPPORTED
- if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)
+ if (change & PNG_FORMAT_FLAG_AFIRST)
{
/* Only relevant if there is an alpha channel - it's particularly
* important to handle this correctly because do_local_compose may
* be set above and then libpng will keep the alpha channel for this
* code to remove.
*/
- if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (format & PNG_FORMAT_FLAG_ALPHA)
{
/* Disable this if doing a local background,
* TODO: remove this when local background is no longer required.
@@ -3914,16 +3780,16 @@ png_image_read_direct(png_voidp argument)
/* If the *output* is 16-bit then we need to check for a byte-swap on this
* architecture.
*/
- if (linear != 0)
+ if (linear)
{
- png_uint_16 le = 0x0001;
+ PNG_CONST png_uint_16 le = 0x0001;
- if ((*(png_const_bytep) & le) != 0)
+ if (*(png_const_bytep)&le)
png_set_swap(png_ptr);
}
/* If change is not now 0 some transformation is missing - error out. */
- if (change != 0)
+ if (change)
png_error(png_ptr, "png_read_image: unsupported transformation");
}
@@ -3935,7 +3801,7 @@ png_image_read_direct(png_voidp argument)
*
* TODO: remove the do_local_background fixup below.
*/
- if (do_local_compose == 0 && do_local_background != 2)
+ if (!do_local_compose && do_local_background != 2)
passes = png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr, info_ptr);
@@ -3943,13 +3809,13 @@ png_image_read_direct(png_voidp argument)
{
png_uint_32 info_format = 0;
- if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
info_format |= PNG_FORMAT_FLAG_COLOR;
- if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
{
/* do_local_compose removes this channel below. */
- if (do_local_compose == 0)
+ if (!do_local_compose)
{
/* do_local_background does the same if required. */
if (do_local_background != 2 ||
@@ -3958,25 +3824,21 @@ png_image_read_direct(png_voidp argument)
}
}
- else if (do_local_compose != 0) /* internal error */
+ else if (do_local_compose) /* internal error */
png_error(png_ptr, "png_image_read: alpha channel lost");
- if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
- info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
- }
-
if (info_ptr->bit_depth == 16)
info_format |= PNG_FORMAT_FLAG_LINEAR;
-#ifdef PNG_FORMAT_BGR_SUPPORTED
- if ((png_ptr->transformations & PNG_BGR) != 0)
- info_format |= PNG_FORMAT_FLAG_BGR;
-#endif
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ info_format |= PNG_FORMAT_FLAG_BGR;
+# endif
-#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
if (do_local_background == 2)
{
- if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ if (format & PNG_FORMAT_FLAG_AFIRST)
info_format |= PNG_FORMAT_FLAG_AFIRST;
}
@@ -4003,26 +3865,26 @@ png_image_read_direct(png_voidp argument)
*/
{
png_voidp first_row = display->buffer;
- ptrdiff_t row_step = display->row_stride;
+ ptrdiff_t row_bytes = display->row_stride;
- if (linear != 0)
- row_step *= 2;
+ if (linear)
+ row_bytes *= 2;
- /* The following adjustment is to ensure that calculations are correct,
- * regardless whether row_step is positive or negative.
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
*/
- if (row_step < 0)
+ if (row_bytes < 0)
{
char *ptr = png_voidcast(char*, first_row);
- ptr += (image->height - 1) * (-row_step);
+ ptr += (image->height-1) * (-row_bytes);
first_row = png_voidcast(png_voidp, ptr);
}
display->first_row = first_row;
- display->row_step = row_step;
+ display->row_bytes = row_bytes;
}
- if (do_local_compose != 0)
+ if (do_local_compose)
{
int result;
png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
@@ -4048,37 +3910,19 @@ png_image_read_direct(png_voidp argument)
return result;
}
- else if (do_local_scale != 0)
- {
- /* For interlaced 16-to-8 conversion, use an intermediate row buffer
- * to avoid buffer overflows in png_combine_row. The local_row is sized
- * for the transformed (8-bit) output, preventing the overflow that would
- * occur if png_combine_row wrote 16-bit data directly to the user buffer.
- */
- int result;
- png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
-
- display->local_row = row;
- result = png_safe_execute(image, png_image_read_direct_scaled, display);
- display->local_row = NULL;
- png_free(png_ptr, row);
-
- return result;
- }
-
else
{
- ptrdiff_t row_step = display->row_step;
+ png_alloc_size_t row_bytes = display->row_bytes;
while (--passes >= 0)
{
- png_uint_32 y = image->height;
- png_bytep row = png_voidcast(png_bytep, display->first_row);
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_read_row(png_ptr, row, NULL);
- row += row_step;
+ row += row_bytes;
}
}
@@ -4088,120 +3932,70 @@ png_image_read_direct(png_voidp argument)
int PNGAPI
png_image_finish_read(png_imagep image, png_const_colorp background,
- void *buffer, png_int_32 row_stride, void *colormap)
+ void *buffer, png_int_32 row_stride, void *colormap)
{
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- /* Check for row_stride overflow. This check is not performed on the
- * original PNG format because it may not occur in the output PNG format
- * and libpng deals with the issues of reading the original.
- */
- unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+ png_uint_32 check;
- /* The following checks just the 'row_stride' calculation to ensure it
- * fits in a signed 32-bit value. Because channels/components can be
- * either 1 or 2 bytes in size the length of a row can still overflow 32
- * bits; this is just to verify that the 'row_stride' argument can be
- * represented.
- */
- if (image->width <= 0x7fffffffU/channels) /* no overflow */
+ if (row_stride == 0)
+ row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+
+ if (row_stride < 0)
+ check = -row_stride;
+
+ else
+ check = row_stride;
+
+ if (image->opaque != NULL && buffer != NULL &&
+ check >= PNG_IMAGE_ROW_STRIDE(*image))
{
- png_uint_32 check;
- png_uint_32 png_row_stride = image->width * channels;
-
- if (row_stride == 0)
- row_stride = (png_int_32)/*SAFE*/png_row_stride;
-
- if (row_stride < 0)
- check = (png_uint_32)(-row_stride);
-
- else
- check = (png_uint_32)row_stride;
-
- /* This verifies 'check', the absolute value of the actual stride
- * passed in and detects overflow in the application calculation (i.e.
- * if the app did actually pass in a non-zero 'row_stride'.
- */
- if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+ (image->colormap_entries > 0 && colormap != NULL))
{
- /* Now check for overflow of the image buffer calculation; this
- * limits the whole image size to 32 bits for API compatibility with
- * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
- *
- * The PNG_IMAGE_BUFFER_SIZE macro is:
- *
- * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
- *
- * And the component size is always 1 or 2, so make sure that the
- * number of *bytes* that the application is saying are available
- * does actually fit into a 32-bit number.
- *
- * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
- * will be changed to use png_alloc_size_t; bigger images can be
- * accommodated on 64-bit systems.
+ int result;
+ png_image_read_control display;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.background = background;
+ display.local_row = NULL;
+
+ /* Choose the correct 'end' routine; for the color-map case all the
+ * setup has already been done.
*/
- if (image->height <=
- 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
- {
- if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
- (image->colormap_entries > 0 && colormap != NULL))
- {
- int result;
- png_image_read_control display;
-
- memset(&display, 0, (sizeof display));
- display.image = image;
- display.buffer = buffer;
- display.row_stride = row_stride;
- display.colormap = colormap;
- display.background = background;
- display.local_row = NULL;
-
- /* Choose the correct 'end' routine; for the color-map case
- * all the setup has already been done.
- */
- if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
- result =
- png_safe_execute(image,
- png_image_read_colormap, &display) &&
- png_safe_execute(image,
- png_image_read_colormapped, &display);
-
- else
- result =
- png_safe_execute(image,
- png_image_read_direct, &display);
-
- png_image_free(image);
- return result;
- }
-
- else
- return png_image_error(image,
- "png_image_finish_read[color-map]: no color-map");
- }
+ if (image->format & PNG_FORMAT_FLAG_COLORMAP)
+ result =
+ png_safe_execute(image, png_image_read_colormap, &display) &&
+ png_safe_execute(image, png_image_read_colormapped, &display);
else
- return png_image_error(image,
- "png_image_finish_read: image too large");
+ result =
+ png_safe_execute(image, png_image_read_direct, &display);
+
+ png_image_free(image);
+ return result;
}
else
return png_image_error(image,
- "png_image_finish_read: invalid argument");
+ "png_image_finish_read[color-map]: no color-map");
}
else
return png_image_error(image,
- "png_image_finish_read: row_stride too large");
+ "png_image_finish_read: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+ "png_image_finish_read: damaged PNG_IMAGE_VERSION");
return 0;
}
-#endif /* SIMPLIFIED_READ */
-#endif /* READ */
+#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngrio.c b/Windows_Libs/Dev/Render/libpng/pngrio.c
index b4a2161..d786440 100644
--- a/Windows_Libs/Dev/Render/libpng/pngrio.c
+++ b/Windows_Libs/Dev/Render/libpng/pngrio.c
@@ -1,9 +1,10 @@
+
/* pngrio.c - functions for data input
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -25,10 +26,10 @@
* reads from a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered reads. This should never be asked
- * to read more than 64K on a 16-bit machine.
+ * to read more then 64K on a 16 bit machine.
*/
void /* PRIVATE */
-png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4, "reading %d bytes", (int)length);
@@ -46,17 +47,17 @@ png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
* than changing the library.
*/
void PNGCBAPI
-png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
- size_t check;
+ png_size_t check;
if (png_ptr == NULL)
return;
- /* fread() returns 0 on error, so it is OK to store this in a size_t
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
- check = fread(data, 1, length, png_voidcast(FILE *, png_ptr->io_ptr));
+ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
if (check != length)
png_error(png_ptr, "Read Error");
@@ -84,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
*/
void PNGAPI
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
- png_rw_ptr read_data_fn)
+ png_rw_ptr read_data_fn)
{
if (png_ptr == NULL)
return;
@@ -101,7 +102,6 @@ png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
png_ptr->read_data_fn = read_data_fn;
#endif
-#ifdef PNG_WRITE_SUPPORTED
/* It is an error to write to a read device */
if (png_ptr->write_data_fn != NULL)
{
@@ -110,10 +110,9 @@ png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
"Can't set both read_data_fn and write_data_fn in the"
" same structure");
}
-#endif
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_ptr->output_flush_fn = NULL;
#endif
}
-#endif /* READ */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngrtran.c b/Windows_Libs/Dev/Render/libpng/pngrtran.c
index 1fce9af..e378ceb 100644
--- a/Windows_Libs/Dev/Render/libpng/pngrtran.c
+++ b/Windows_Libs/Dev/Render/libpng/pngrtran.c
@@ -1,9 +1,10 @@
+
/* pngrtran.c - transforms the data in a row for PNG readers
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -17,23 +18,6 @@
#include "pngpriv.h"
-#ifdef PNG_ARM_NEON_IMPLEMENTATION
-# if PNG_ARM_NEON_IMPLEMENTATION == 1
-# define PNG_ARM_NEON_INTRINSICS_AVAILABLE
-# if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64)
-# include
-# else
-# include
-# endif
-# endif
-#endif
-
-#ifdef PNG_RISCV_RVV_IMPLEMENTATION
-# if PNG_RISCV_RVV_IMPLEMENTATION == 1
-# define PNG_RISCV_RVV_INTRINSICS_AVAILABLE
-# endif
-#endif
-
#ifdef PNG_READ_SUPPORTED
/* Set the action on getting a CRC error for an ancillary or critical chunk. */
@@ -64,8 +48,7 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
png_warning(png_ptr,
- "Can't discard critical data on CRC error");
- /* FALLTHROUGH */
+ "Can't discard critical data on CRC error");
case PNG_CRC_ERROR_QUIT: /* Error/quit */
case PNG_CRC_DEFAULT:
@@ -108,17 +91,16 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Is it OK to set a transformation now? Only if png_start_read_image or
* png_read_update_info have not been called. It is not necessary for the IHDR
- * to have been read in all cases; the need_IHDR parameter allows for this
- * check too.
+ * to have been read in all cases, the parameter allows for this check too.
*/
static int
png_rtran_ok(png_structrp png_ptr, int need_IHDR)
{
if (png_ptr != NULL)
{
- if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+ if (png_ptr->flags & PNG_FLAG_ROW_INIT)
png_app_error(png_ptr,
- "invalid after png_start_read_image or png_read_update_info");
+ "invalid after png_start_read_image or png_read_update_info");
else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_app_error(png_ptr, "invalid before the PNG header has been read");
@@ -145,7 +127,7 @@ png_set_background_fixed(png_structrp png_ptr,
{
png_debug(1, "in png_set_background_fixed");
- if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
+ if (!png_rtran_ok(png_ptr, 0) || background_color == NULL)
return;
if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
@@ -161,7 +143,7 @@ png_set_background_fixed(png_structrp png_ptr,
png_ptr->background = *background_color;
png_ptr->background_gamma = background_gamma;
png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
- if (need_expand != 0)
+ if (need_expand)
png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
else
png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
@@ -176,7 +158,7 @@ png_set_background(png_structrp png_ptr,
png_set_background_fixed(png_ptr, background_color, background_gamma_code,
need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
}
-# endif /* FLOATING_POINT */
+# endif /* FLOATING_POINT */
#endif /* READ_BACKGROUND */
/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
@@ -189,7 +171,7 @@ png_set_scale_16(png_structrp png_ptr)
{
png_debug(1, "in png_set_scale_16");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= PNG_SCALE_16_TO_8;
@@ -203,7 +185,7 @@ png_set_strip_16(png_structrp png_ptr)
{
png_debug(1, "in png_set_strip_16");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= PNG_16_TO_8;
@@ -216,7 +198,7 @@ png_set_strip_alpha(png_structrp png_ptr)
{
png_debug(1, "in png_set_strip_alpha");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= PNG_STRIP_ALPHA;
@@ -224,59 +206,9 @@ png_set_strip_alpha(png_structrp png_ptr)
#endif
#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
-/* PNGv3 conformance: this private API exists to resolve the now mandatory error
- * resolution when multiple conflicting sources of gamma or colour space
- * information are available.
- *
- * Terminology (assuming power law, "gamma", encodings):
- * "screen" gamma: a power law imposed by the output device when digital
- * samples are converted to visible light output. The EOTF - volage to
- * luminance on output.
- *
- * "file" gamma: a power law used to encode luminance levels from the input
- * data (the scene or the mastering display system) into digital voltages.
- * The OETF - luminance to voltage on input.
- *
- * gamma "correction": a power law matching the **inverse** of the overall
- * transfer function from input luminance levels to output levels. The
- * **inverse** of the OOTF; the correction "corrects" for the OOTF by aiming
- * to make the overall OOTF (including the correction) linear.
- *
- * It is important to understand this terminology because the defined terms are
- * scattered throughout the libpng code and it is very easy to end up with the
- * inverse of the power law required.
- *
- * Variable and struct::member names:
- * file_gamma OETF how the PNG data was encoded
- *
- * screen_gamma EOTF how the screen will decode digital levels
- *
- * -- not used -- OOTF the net effect OETF x EOTF
- * gamma_correction the inverse of OOTF to make the result linear
- *
- * All versions of libpng require a call to "png_set_gamma" to establish the
- * "screen" gamma, the power law representing the EOTF. png_set_gamma may also
- * set or default the "file" gamma; the OETF. gamma_correction is calculated
- * internally.
- *
- * The earliest libpng versions required file_gamma to be supplied to set_gamma.
- * Later versions started allowing png_set_gamma and, later, png_set_alpha_mode,
- * to cause defaulting from the file data.
- *
- * PNGv3 mandated a particular form for this defaulting, one that is compatible
- * with what libpng did except that if libpng detected inconsistencies it marked
- * all the chunks as "invalid". PNGv3 effectively invalidates this prior code.
- *
- * Behaviour implemented below:
- * translate_gamma_flags(gamma, is_screen)
- * The libpng-1.6 API for the gamma parameters to libpng APIs
- * (png_set_gamma and png_set_alpha_mode at present). This allows the
- * 'gamma' value to be passed as a png_fixed_point number or as one of a
- * set of integral values for specific "well known" examples of transfer
- * functions. This is compatible with PNGv3.
- */
static png_fixed_point
-translate_gamma_flags(png_fixed_point output_gamma, int is_screen)
+translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
+ int is_screen)
{
/* Check for flag values. The main reason for having the old Mac value as a
* flag is that it is pretty near impossible to work out what the correct
@@ -286,7 +218,15 @@ translate_gamma_flags(png_fixed_point output_gamma, int is_screen)
if (output_gamma == PNG_DEFAULT_sRGB ||
output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
{
- if (is_screen != 0)
+ /* If there is no sRGB support this just sets the gamma to the standard
+ * sRGB value. (This is a side effect of using this function!)
+ */
+# ifdef PNG_READ_sRGB_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ if (is_screen)
output_gamma = PNG_GAMMA_sRGB;
else
output_gamma = PNG_GAMMA_sRGB_INVERSE;
@@ -295,7 +235,7 @@ translate_gamma_flags(png_fixed_point output_gamma, int is_screen)
else if (output_gamma == PNG_GAMMA_MAC_18 ||
output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
{
- if (is_screen != 0)
+ if (is_screen)
output_gamma = PNG_GAMMA_MAC_OLD;
else
output_gamma = PNG_GAMMA_MAC_INVERSE;
@@ -327,63 +267,36 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma)
return (png_fixed_point)output_gamma;
}
# endif
-
-static int
-unsupported_gamma(png_structrp png_ptr, png_fixed_point gamma, int warn)
-{
- /* Validate a gamma value to ensure it is in a reasonable range. The value
- * is expected to be 1 or greater, but this range test allows for some
- * viewing correction values. The intent is to weed out the API users
- * who might use the inverse of the gamma value accidentally!
- *
- * 1.6.47: apply the test in png_set_gamma as well but only warn and return
- * false if it fires.
- *
- * TODO: 1.8: make this an app_error in png_set_gamma as well.
- */
- if (gamma < PNG_LIB_GAMMA_MIN || gamma > PNG_LIB_GAMMA_MAX)
- {
-# define msg "gamma out of supported range"
- if (warn)
- png_app_warning(png_ptr, msg);
- else
- png_app_error(png_ptr, msg);
- return 1;
-# undef msg
- }
-
- return 0;
-}
#endif /* READ_ALPHA_MODE || READ_GAMMA */
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
void PNGFAPI
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
- png_fixed_point output_gamma)
+ png_fixed_point output_gamma)
{
- png_fixed_point file_gamma;
int compose = 0;
+ png_fixed_point file_gamma;
- png_debug(1, "in png_set_alpha_mode_fixed");
+ png_debug(1, "in png_set_alpha_mode");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
- output_gamma = translate_gamma_flags(output_gamma, 1/*screen*/);
- if (unsupported_gamma(png_ptr, output_gamma, 0/*error*/))
- return;
+ output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
+
+ /* Validate the value to ensure it is in a reasonable range. The value
+ * is expected to be 1 or greater, but this range test allows for some
+ * viewing correction values. The intent is to weed out users of this API
+ * who use the inverse of the gamma value accidentally! Since some of these
+ * values are reasonable this may have to be changed.
+ */
+ if (output_gamma < 70000 || output_gamma > 300000)
+ png_error(png_ptr, "output gamma out of expected range");
/* The default file gamma is the inverse of the output gamma; the output
- * gamma may be changed below so get the file value first. The default_gamma
- * is set here and from the simplified API (which uses a different algorithm)
- * so don't overwrite a set value:
+ * gamma may be changed below so get the file value first:
*/
- file_gamma = png_ptr->default_gamma;
- if (file_gamma == 0)
- {
- file_gamma = png_reciprocal(output_gamma);
- png_ptr->default_gamma = file_gamma;
- }
+ file_gamma = png_reciprocal(output_gamma);
/* There are really 8 possibilities here, composed of any combination
* of:
@@ -434,23 +347,33 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
png_error(png_ptr, "invalid alpha mode");
}
- /* Set the screen gamma values: */
+ /* Only set the default gamma if the file gamma has not been set (this has
+ * the side effect that the gamma in a second call to png_set_alpha_mode will
+ * be ignored.)
+ */
+ if (png_ptr->colorspace.gamma == 0)
+ {
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
+
+ /* But always set the output gamma: */
png_ptr->screen_gamma = output_gamma;
/* Finally, if pre-multiplying, set the background fields to achieve the
* desired result.
*/
- if (compose != 0)
+ if (compose)
{
/* And obtain alpha pre-multiplication by composing on black: */
memset(&png_ptr->background, 0, (sizeof png_ptr->background));
- png_ptr->background_gamma = file_gamma; /* just in case */
+ png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
- if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ if (png_ptr->transformations & PNG_COMPOSE)
png_error(png_ptr,
- "conflicting calls to set alpha mode and background");
+ "conflicting calls to set alpha mode and background");
png_ptr->transformations |= PNG_COMPOSE;
}
@@ -461,7 +384,7 @@ void PNGAPI
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
{
png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
- output_gamma));
+ output_gamma));
}
# endif
#endif
@@ -470,7 +393,7 @@ png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
/* Dither file to 8-bit. Supply a palette, the current number
* of elements in the palette, the maximum number of elements
* allowed, and a histogram if possible. If the current number
- * of colors is greater than the maximum number, the palette will be
+ * of colors is greater then the maximum number, the palette will be
* modified to fit in the maximum number. "full_quantize" indicates
* whether we need a quantizing cube set up for RGB images, or if we
* simply are reducing the number of colors in a paletted image.
@@ -492,28 +415,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
{
png_debug(1, "in png_set_quantize");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= PNG_QUANTIZE;
- if (full_quantize == 0)
+ if (!full_quantize)
{
int i;
- /* Initialize the array to index colors.
- *
- * Ensure quantize_index can fit 256 elements (PNG_MAX_PALETTE_LENGTH)
- * rather than num_palette elements. This is to prevent buffer overflows
- * caused by malformed PNG files with out-of-range palette indices.
- *
- * Be careful to avoid leaking memory. Applications are allowed to call
- * this function more than once per png_struct.
- */
- png_free(png_ptr, png_ptr->quantize_index);
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
- PNG_MAX_PALETTE_LENGTH);
- for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++)
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+ for (i = 0; i < num_palette; i++)
png_ptr->quantize_index[i] = (png_byte)i;
}
@@ -525,14 +438,15 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
* Perhaps not the best solution, but good enough.
*/
- png_bytep quantize_sort;
- int i, j;
+ int i;
- /* Initialize the local array to sort colors. */
- quantize_sort = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)num_palette);
+ /* Initialize an array to sort colors */
+ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+
+ /* Initialize the quantize_sort array */
for (i = 0; i < num_palette; i++)
- quantize_sort[i] = (png_byte)i;
+ png_ptr->quantize_sort[i] = (png_byte)i;
/* Find the least used palette entries by starting a
* bubble sort, and running it until we have sorted
@@ -544,41 +458,42 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
for (i = num_palette - 1; i >= maximum_colors; i--)
{
int done; /* To stop early if the list is pre-sorted */
+ int j;
done = 1;
for (j = 0; j < i; j++)
{
- if (histogram[quantize_sort[j]]
- < histogram[quantize_sort[j + 1]])
+ if (histogram[png_ptr->quantize_sort[j]]
+ < histogram[png_ptr->quantize_sort[j + 1]])
{
png_byte t;
- t = quantize_sort[j];
- quantize_sort[j] = quantize_sort[j + 1];
- quantize_sort[j + 1] = t;
+ t = png_ptr->quantize_sort[j];
+ png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
+ png_ptr->quantize_sort[j + 1] = t;
done = 0;
}
}
- if (done != 0)
+ if (done)
break;
}
/* Swap the palette around, and set up a table, if necessary */
- if (full_quantize != 0)
+ if (full_quantize)
{
- j = num_palette;
+ int j = num_palette;
/* Put all the useful colors within the max, but don't
* move the others.
*/
for (i = 0; i < maximum_colors; i++)
{
- if ((int)quantize_sort[i] >= maximum_colors)
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
{
do
j--;
- while ((int)quantize_sort[j] >= maximum_colors);
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
palette[i] = palette[j];
}
@@ -586,7 +501,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
}
else
{
- j = num_palette;
+ int j = num_palette;
/* Move all the used colors inside the max limit, and
* develop a translation table.
@@ -594,13 +509,13 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
for (i = 0; i < maximum_colors; i++)
{
/* Only move the colors we need to */
- if ((int)quantize_sort[i] >= maximum_colors)
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
{
png_color tmp_color;
do
j--;
- while ((int)quantize_sort[j] >= maximum_colors);
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
tmp_color = palette[j];
palette[j] = palette[i];
@@ -638,7 +553,8 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
}
}
}
- png_free(png_ptr, quantize_sort);
+ png_free(png_ptr, png_ptr->quantize_sort);
+ png_ptr->quantize_sort = NULL;
}
else
{
@@ -660,9 +576,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)num_palette);
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_alloc_size_t)num_palette);
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
/* Initialize the sort array */
for (i = 0; i < num_palette; i++)
@@ -671,7 +587,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_ptr->palette_to_index[i] = (png_byte)i;
}
- hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
+ hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
(sizeof (png_dsortp))));
num_new_palette = num_palette;
@@ -702,14 +618,14 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
{
t = (png_dsortp)png_malloc_warn(png_ptr,
- (png_alloc_size_t)(sizeof (png_dsort)));
+ (png_uint_32)(sizeof (png_dsort)));
if (t == NULL)
break;
t->next = hash[d];
- t->left = png_ptr->palette_to_index[i];
- t->right = png_ptr->palette_to_index[j];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
hash[d] = t;
}
}
@@ -747,7 +663,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
num_new_palette--;
palette[png_ptr->index_to_palette[j]]
= palette[num_new_palette];
- if (full_quantize == 0)
+ if (!full_quantize)
{
int k;
@@ -815,7 +731,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
}
png_ptr->num_palette = (png_uint_16)num_palette;
- if (full_quantize != 0)
+ if (full_quantize)
{
int i;
png_bytep distance;
@@ -824,14 +740,15 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
int num_red = (1 << PNG_QUANTIZE_RED_BITS);
int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
- size_t num_entries = ((size_t)1 << total_bits);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
- (png_alloc_size_t)(num_entries));
+ (png_uint_32)(num_entries * (sizeof (png_byte))));
- distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries);
+ distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ (sizeof (png_byte))));
- memset(distance, 0xff, num_entries);
+ memset(distance, 0xff, num_entries * (sizeof (png_byte)));
for (i = 0; i < num_palette; i++)
{
@@ -876,21 +793,21 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_free(png_ptr, distance);
}
}
-#endif /* READ_QUANTIZE */
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
#ifdef PNG_READ_GAMMA_SUPPORTED
void PNGFAPI
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
- png_fixed_point file_gamma)
+ png_fixed_point file_gamma)
{
png_debug(1, "in png_set_gamma_fixed");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
/* New in libpng-1.5.4 - reserve particular negative values as flags. */
- scrn_gamma = translate_gamma_flags(scrn_gamma, 1/*screen*/);
- file_gamma = translate_gamma_flags(file_gamma, 0/*file*/);
+ scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
+ file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
/* Checking the gamma values for being >0 was added in 1.5.4 along with the
* premultiplied alpha support; this actually hides an undocumented feature
@@ -904,19 +821,17 @@ png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
* libpng-1.6.0.
*/
if (file_gamma <= 0)
- png_app_error(png_ptr, "invalid file gamma in png_set_gamma");
+ png_error(png_ptr, "invalid file gamma in png_set_gamma");
+
if (scrn_gamma <= 0)
- png_app_error(png_ptr, "invalid screen gamma in png_set_gamma");
+ png_error(png_ptr, "invalid screen gamma in png_set_gamma");
- if (unsupported_gamma(png_ptr, file_gamma, 1/*warn*/) ||
- unsupported_gamma(png_ptr, scrn_gamma, 1/*warn*/))
- return;
-
- /* 1.6.47: png_struct::file_gamma and png_struct::screen_gamma are now only
- * written by this API. This removes dependencies on the order of API calls
- * and allows the complex gamma checks to be delayed until needed.
+ /* Set the gamma values unconditionally - this overrides the value in the PNG
+ * file if a gAMA chunk was present. png_set_alpha_mode provides a
+ * different, easier, way to default the file gamma.
*/
- png_ptr->file_gamma = file_gamma;
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
png_ptr->screen_gamma = scrn_gamma;
}
@@ -925,9 +840,9 @@ void PNGAPI
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
{
png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
- convert_gamma_value(png_ptr, file_gamma));
+ convert_gamma_value(png_ptr, file_gamma));
}
-# endif /* FLOATING_POINT */
+# endif /* FLOATING_POINT_SUPPORTED */
#endif /* READ_GAMMA */
#ifdef PNG_READ_EXPAND_SUPPORTED
@@ -940,7 +855,7 @@ png_set_expand(png_structrp png_ptr)
{
png_debug(1, "in png_set_expand");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
@@ -970,7 +885,7 @@ png_set_palette_to_rgb(png_structrp png_ptr)
{
png_debug(1, "in png_set_palette_to_rgb");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
@@ -982,7 +897,7 @@ png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
{
png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= PNG_EXPAND;
@@ -994,12 +909,12 @@ png_set_tRNS_to_alpha(png_structrp png_ptr)
{
png_debug(1, "in png_set_tRNS_to_alpha");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
}
-#endif /* READ_EXPAND */
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
#ifdef PNG_READ_EXPAND_16_SUPPORTED
/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
@@ -1010,7 +925,7 @@ png_set_expand_16(png_structrp png_ptr)
{
png_debug(1, "in png_set_expand_16");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
@@ -1023,7 +938,7 @@ png_set_gray_to_rgb(png_structrp png_ptr)
{
png_debug(1, "in png_set_gray_to_rgb");
- if (png_rtran_ok(png_ptr, 0) == 0)
+ if (!png_rtran_ok(png_ptr, 0))
return;
/* Because rgb must be 8 bits or more: */
@@ -1037,14 +952,14 @@ void PNGFAPI
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
png_fixed_point red, png_fixed_point green)
{
- png_debug(1, "in png_set_rgb_to_gray_fixed");
+ png_debug(1, "in png_set_rgb_to_gray");
/* Need the IHDR here because of the check on color_type below. */
/* TODO: fix this */
- if (png_rtran_ok(png_ptr, 1) == 0)
+ if (!png_rtran_ok(png_ptr, 1))
return;
- switch (error_action)
+ switch(error_action)
{
case PNG_ERROR_ACTION_NONE:
png_ptr->transformations |= PNG_RGB_TO_GRAY;
@@ -1060,6 +975,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
default:
png_error(png_ptr, "invalid error action to rgb_to_gray");
+ break;
}
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
@@ -1071,7 +987,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
* that it just worked and get a memory overwrite.
*/
png_error(png_ptr,
- "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+ "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
/* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
}
@@ -1082,7 +998,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
png_uint_16 red_int, green_int;
/* NOTE: this calculation does not round, but this behavior is retained
- * for consistency; the inaccuracy is very small. The code here always
+ * for consistency, the inaccuracy is very small. The code here always
* overwrites the coefficients, regardless of whether they have been
* defaulted or set already.
*/
@@ -1094,9 +1010,26 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
png_ptr->rgb_to_gray_coefficients_set = 1;
}
- else if (red >= 0 && green >= 0)
- png_app_warning(png_ptr,
+ else
+ {
+ if (red >= 0 && green >= 0)
+ png_app_warning(png_ptr,
"ignoring out of range rgb_to_gray coefficients");
+
+ /* Use the defaults, from the cHRM chunk if set, else the historical
+ * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
+ * png_do_rgb_to_gray for more discussion of the values. In this case
+ * the coefficients are not marked as 'set' and are not overwritten if
+ * something has already provided a default.
+ */
+ if (png_ptr->rgb_to_gray_red_coeff == 0 &&
+ png_ptr->rgb_to_gray_green_coeff == 0)
+ {
+ png_ptr->rgb_to_gray_red_coeff = 6968;
+ png_ptr->rgb_to_gray_green_coeff = 23434;
+ /* png_ptr->rgb_to_gray_blue_coeff = 2366; */
+ }
+ }
}
}
@@ -1107,10 +1040,10 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
void PNGAPI
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
- double green)
+ double green)
{
png_set_rgb_to_gray_fixed(png_ptr, error_action,
- png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+ png_fixed(png_ptr, red, "rgb to gray red coefficient"),
png_fixed(png_ptr, green, "rgb to gray green coefficient"));
}
#endif /* FLOATING POINT */
@@ -1120,8 +1053,8 @@ png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
void PNGAPI
-png_set_read_user_transform_fn(png_structrp png_ptr,
- png_user_transform_ptr read_user_transform_fn)
+png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
{
png_debug(1, "in png_set_read_user_transform_fn");
@@ -1158,7 +1091,7 @@ png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
* the palette.
*/
-/* For the moment 'png_init_palette_transformations' and
+/*For the moment 'png_init_palette_transformations' and
* 'png_init_rgb_transformations' only do some flag canceling optimizations.
* The intent is that these two routines should have palette or rgb operations
* extracted from 'png_init_read_transformations'.
@@ -1183,31 +1116,25 @@ png_init_palette_transformations(png_structrp png_ptr)
/* Ignore if all the entries are opaque (unlikely!) */
for (i=0; inum_trans; ++i)
- {
if (png_ptr->trans_alpha[i] == 255)
continue;
else if (png_ptr->trans_alpha[i] == 0)
input_has_transparency = 1;
else
- {
- input_has_transparency = 1;
input_has_alpha = 1;
- break;
- }
- }
}
/* If no alpha we can optimize. */
- if (input_has_alpha == 0)
+ if (!input_has_alpha)
{
/* Any alpha means background and associative alpha processing is
- * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+ * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
* and ENCODE_ALPHA are irrelevant.
*/
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
- if (input_has_transparency == 0)
+ if (!input_has_transparency)
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
}
@@ -1220,8 +1147,8 @@ png_init_palette_transformations(png_structrp png_ptr)
/* The following code cannot be entered in the alpha pre-multiplication case
* because PNG_BACKGROUND_EXPAND is cancelled below.
*/
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
- (png_ptr->transformations & PNG_EXPAND) != 0)
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND))
{
{
png_ptr->background.red =
@@ -1232,24 +1159,24 @@ png_init_palette_transformations(png_structrp png_ptr)
png_ptr->palette[png_ptr->background.index].blue;
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
- {
- if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
- {
- /* Invert the alpha channel (in tRNS) unless the pixels are
- * going to be expanded, in which case leave it for later
- */
- int i, istop = png_ptr->num_trans;
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ {
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ /* Invert the alpha channel (in tRNS) unless the pixels are
+ * going to be expanded, in which case leave it for later
+ */
+ int i, istop = png_ptr->num_trans;
- for (i = 0; i < istop; i++)
- png_ptr->trans_alpha[i] =
- (png_byte)(255 - png_ptr->trans_alpha[i]);
- }
- }
-#endif /* READ_INVERT_ALPHA */
+ for (i=0; itrans_alpha[i] = (png_byte)(255 -
+ png_ptr->trans_alpha[i]);
+ }
+ }
+#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
}
} /* background expand and (therefore) no alpha association. */
-#endif /* READ_EXPAND && READ_BACKGROUND */
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
}
static void /* PRIVATE */
@@ -1263,10 +1190,10 @@ png_init_rgb_transformations(png_structrp png_ptr)
int input_has_transparency = png_ptr->num_trans > 0;
/* If no alpha we can optimize. */
- if (input_has_alpha == 0)
+ if (!input_has_alpha)
{
/* Any alpha means background and associative alpha processing is
- * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+ * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
* and ENCODE_ALPHA are irrelevant.
*/
# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
@@ -1274,7 +1201,7 @@ png_init_rgb_transformations(png_structrp png_ptr)
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
# endif
- if (input_has_transparency == 0)
+ if (!input_has_transparency)
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
}
@@ -1287,9 +1214,9 @@ png_init_rgb_transformations(png_structrp png_ptr)
/* The following code cannot be entered in the alpha pre-multiplication case
* because PNG_BACKGROUND_EXPAND is cancelled below.
*/
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
- (png_ptr->transformations & PNG_EXPAND) != 0 &&
- (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND) &&
+ !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
/* i.e., GRAY or GRAY_ALPHA */
{
{
@@ -1317,7 +1244,7 @@ png_init_rgb_transformations(png_structrp png_ptr)
default:
case 8:
- /* FALLTHROUGH */ /* (Already 8 bits) */
+ /* FALL THROUGH (Already 8 bits) */
case 16:
/* Already a full 16 bits */
@@ -1327,90 +1254,16 @@ png_init_rgb_transformations(png_structrp png_ptr)
png_ptr->background.red = png_ptr->background.green =
png_ptr->background.blue = (png_uint_16)gray;
- if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
{
png_ptr->trans_color.red = png_ptr->trans_color.green =
png_ptr->trans_color.blue = (png_uint_16)trans_gray;
}
}
} /* background expand and (therefore) no alpha association. */
-#endif /* READ_EXPAND && READ_BACKGROUND */
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
}
-#ifdef PNG_READ_GAMMA_SUPPORTED
-png_fixed_point /* PRIVATE */
-png_resolve_file_gamma(png_const_structrp png_ptr)
-{
- png_fixed_point file_gamma;
-
- /* The file gamma is determined by these precedence rules, in this order
- * (i.e. use the first value found):
- *
- * png_set_gamma; png_struct::file_gammma if not zero, then:
- * png_struct::chunk_gamma if not 0 (determined the PNGv3 rules), then:
- * png_set_gamma; 1/png_struct::screen_gamma if not zero
- *
- * 0 (i.e. do no gamma handling)
- */
- file_gamma = png_ptr->file_gamma;
- if (file_gamma != 0)
- return file_gamma;
-
- file_gamma = png_ptr->chunk_gamma;
- if (file_gamma != 0)
- return file_gamma;
-
- file_gamma = png_ptr->default_gamma;
- if (file_gamma != 0)
- return file_gamma;
-
- /* If png_reciprocal oveflows it returns 0 which indicates to the caller that
- * there is no usable file gamma. (The checks added to png_set_gamma and
- * png_set_alpha_mode should prevent a screen_gamma which would overflow.)
- */
- if (png_ptr->screen_gamma != 0)
- file_gamma = png_reciprocal(png_ptr->screen_gamma);
-
- return file_gamma;
-}
-
-static int
-png_init_gamma_values(png_structrp png_ptr)
-{
- /* The following temporary indicates if overall gamma correction is
- * required.
- */
- int gamma_correction = 0;
- png_fixed_point file_gamma, screen_gamma;
-
- /* Resolve the file_gamma. See above: if png_ptr::screen_gamma is set
- * file_gamma will always be set here:
- */
- file_gamma = png_resolve_file_gamma(png_ptr);
- screen_gamma = png_ptr->screen_gamma;
-
- if (file_gamma > 0) /* file has been set */
- {
- if (screen_gamma > 0) /* screen set too */
- gamma_correction = png_gamma_threshold(file_gamma, screen_gamma);
-
- else
- /* Assume the output matches the input; a long time default behavior
- * of libpng, although the standard has nothing to say about this.
- */
- screen_gamma = png_reciprocal(file_gamma);
- }
-
- else /* both unset, prevent corrections: */
- file_gamma = screen_gamma = PNG_FP_1;
-
- png_ptr->file_gamma = file_gamma;
- png_ptr->screen_gamma = screen_gamma;
- return gamma_correction;
-
-}
-#endif /* READ_GAMMA */
-
void /* PRIVATE */
png_init_read_transformations(png_structrp png_ptr)
{
@@ -1430,26 +1283,63 @@ png_init_read_transformations(png_structrp png_ptr)
* the test needs to be performed later - here. In addition prior to 1.5.4
* the tests were repeated for the PALETTE color type here - this is no
* longer necessary (and doesn't seem to have been necessary before.)
- *
- * PNGv3: the new mandatory precedence/priority rules for colour space chunks
- * are handled here (by calling the above function).
- *
- * Turn the gamma transformation on or off as appropriate. Notice that
- * PNG_GAMMA just refers to the file->screen correction. Alpha composition
- * may independently cause gamma correction because it needs linear data
- * (e.g. if the file has a gAMA chunk but the screen gamma hasn't been
- * specified.) In any case this flag may get turned off in the code
- * immediately below if the transform can be handled outside the row loop.
*/
- if (png_init_gamma_values(png_ptr) != 0)
- png_ptr->transformations |= PNG_GAMMA;
+ {
+ /* The following temporary indicates if overall gamma correction is
+ * required.
+ */
+ int gamma_correction = 0;
- else
- png_ptr->transformations &= ~PNG_GAMMA;
+ if (png_ptr->colorspace.gamma != 0) /* has been set */
+ {
+ if (png_ptr->screen_gamma != 0) /* screen set too */
+ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+
+ else
+ /* Assume the output matches the input; a long time default behavior
+ * of libpng, although the standard has nothing to say about this.
+ */
+ png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
+ }
+
+ else if (png_ptr->screen_gamma != 0)
+ /* The converse - assume the file matches the screen, note that this
+ * perhaps undesireable default can (from 1.5.4) be changed by calling
+ * png_set_alpha_mode (even if the alpha handling mode isn't required
+ * or isn't changed from the default.)
+ */
+ png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
+
+ else /* neither are set */
+ /* Just in case the following prevents any processing - file and screen
+ * are both assumed to be linear and there is no way to introduce a
+ * third gamma value other than png_set_background with 'UNIQUE', and,
+ * prior to 1.5.4
+ */
+ png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
+
+ /* We have a gamma value now. */
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Now turn the gamma transformation on or off as appropriate. Notice
+ * that PNG_GAMMA just refers to the file->screen correction. Alpha
+ * composition may independently cause gamma correction because it needs
+ * linear data (e.g. if the file has a gAMA chunk but the screen gamma
+ * hasn't been specified.) In any case this flag may get turned off in
+ * the code immediately below if the transform can be handled outside the
+ * row loop.
+ */
+ if (gamma_correction)
+ png_ptr->transformations |= PNG_GAMMA;
+
+ else
+ png_ptr->transformations &= ~PNG_GAMMA;
+ }
#endif
/* Certain transformations have the effect of preventing other
- * transformations that happen afterward in png_do_read_transformations;
+ * transformations that happen afterward in png_do_read_transformations,
* resolve the interdependencies here. From the code of
* png_do_read_transformations the order is:
*
@@ -1467,19 +1357,19 @@ png_init_read_transformations(png_structrp png_ptr)
* 12) PNG_EXPAND_16
* 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
* 14) PNG_INVERT_MONO
- * 15) PNG_INVERT_ALPHA
- * 16) PNG_SHIFT
- * 17) PNG_PACK
- * 18) PNG_BGR
- * 19) PNG_PACKSWAP
- * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
+ * 15) PNG_SHIFT
+ * 16) PNG_PACK
+ * 17) PNG_BGR
+ * 18) PNG_PACKSWAP
+ * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
+ * 20) PNG_INVERT_ALPHA
* 21) PNG_SWAP_ALPHA
* 22) PNG_SWAP_BYTES
* 23) PNG_USER_TRANSFORM [must be last]
*/
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
- (png_ptr->transformations & PNG_COMPOSE) == 0)
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ !(png_ptr->transformations & PNG_COMPOSE))
{
/* Stripping the alpha channel happens immediately after the 'expand'
* transformations, before all other transformation, so it cancels out
@@ -1505,7 +1395,7 @@ png_init_read_transformations(png_structrp png_ptr)
/* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
* settings will have no effect.
*/
- if (png_gamma_significant(png_ptr->screen_gamma) == 0)
+ if (!png_gamma_significant(png_ptr->screen_gamma))
{
png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
@@ -1516,8 +1406,8 @@ png_init_read_transformations(png_structrp png_ptr)
/* Make sure the coefficients for the rgb to gray conversion are set
* appropriately.
*/
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
- png_set_rgb_coefficients(png_ptr);
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ png_colorspace_set_rgb_coefficients(png_ptr);
#endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
@@ -1537,23 +1427,23 @@ png_init_read_transformations(png_structrp png_ptr)
* png_set_background, along with the bit depth, then the code has a record
* of exactly what color space the background is currently in.
*/
- if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
+ if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
{
/* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
* the file was grayscale the background value is gray.
*/
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
}
- else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ else if (png_ptr->transformations & PNG_COMPOSE)
{
/* PNG_COMPOSE: png_set_background was called with need_expand false,
* so the color is in the color space of the output or png_set_alpha_mode
* was called and the color is black. Ignore RGB_TO_GRAY because that
* happens before GRAY_TO_RGB.
*/
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
{
if (png_ptr->background.red == png_ptr->background.green &&
png_ptr->background.red == png_ptr->background.blue)
@@ -1563,8 +1453,8 @@ png_init_read_transformations(png_structrp png_ptr)
}
}
}
-#endif /* READ_EXPAND && READ_BACKGROUND */
-#endif /* READ_GRAY_TO_RGB */
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
+#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
/* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
* can be performed directly on the palette, and some (such as rgb to gray)
@@ -1585,10 +1475,10 @@ png_init_read_transformations(png_structrp png_ptr)
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
defined(PNG_READ_EXPAND_16_SUPPORTED)
- if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
- (png_ptr->transformations & PNG_COMPOSE) != 0 &&
- (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
- png_ptr->bit_depth != 16)
+ if ((png_ptr->transformations & PNG_EXPAND_16) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ png_ptr->bit_depth != 16)
{
/* TODO: fix this. Because the expand_16 operation is after the compose
* handling the background color must be 8, not 16, bits deep, but the
@@ -1607,15 +1497,15 @@ png_init_read_transformations(png_structrp png_ptr)
CHOP(png_ptr->background.gray);
# undef CHOP
}
-#endif /* READ_BACKGROUND && READ_EXPAND_16 */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
(defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
- if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
- (png_ptr->transformations & PNG_COMPOSE) != 0 &&
- (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
- png_ptr->bit_depth == 16)
+ if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ png_ptr->bit_depth == 16)
{
/* On the other hand, if a 16-bit file is to be reduced to 8-bits per
* component this will also happen after PNG_COMPOSE and so the background
@@ -1658,24 +1548,25 @@ png_init_read_transformations(png_structrp png_ptr)
* file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
* tables.
*/
- if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
- ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
- (png_gamma_significant(png_ptr->file_gamma) != 0 ||
- png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
- ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
- (png_gamma_significant(png_ptr->file_gamma) != 0 ||
- png_gamma_significant(png_ptr->screen_gamma) != 0
+ if ((png_ptr->transformations & PNG_GAMMA)
+ || ((png_ptr->transformations & PNG_RGB_TO_GRAY)
+ && (png_gamma_significant(png_ptr->colorspace.gamma) ||
+ png_gamma_significant(png_ptr->screen_gamma)))
+ || ((png_ptr->transformations & PNG_COMPOSE)
+ && (png_gamma_significant(png_ptr->colorspace.gamma)
+ || png_gamma_significant(png_ptr->screen_gamma)
# ifdef PNG_READ_BACKGROUND_SUPPORTED
- || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
- png_gamma_significant(png_ptr->background_gamma) != 0)
+ || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE
+ && png_gamma_significant(png_ptr->background_gamma))
# endif
- )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
- png_gamma_significant(png_ptr->screen_gamma) != 0))
+ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)
+ && png_gamma_significant(png_ptr->screen_gamma))
+ )
{
png_build_gamma_table(png_ptr, png_ptr->bit_depth);
#ifdef PNG_READ_BACKGROUND_SUPPORTED
- if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ if (png_ptr->transformations & PNG_COMPOSE)
{
/* Issue a warning about this combination: because RGB_TO_GRAY is
* optimized to do the gamma transform if present yet do_background has
@@ -1683,11 +1574,11 @@ png_init_read_transformations(png_structrp png_ptr)
* double-gamma-correction happens. This is true in all versions of
* libpng to date.
*/
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
png_warning(png_ptr,
- "libpng does not support gamma+background+rgb_to_gray");
+ "libpng does not support gamma+background+rgb_to_gray");
- if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
/* We don't get to here unless there is a tRNS chunk with non-opaque
* entries - see the checking code at the start of this function.
@@ -1719,15 +1610,15 @@ png_init_read_transformations(png_structrp png_ptr)
break;
case PNG_BACKGROUND_GAMMA_FILE:
- g = png_reciprocal(png_ptr->file_gamma);
- gs = png_reciprocal2(png_ptr->file_gamma,
- png_ptr->screen_gamma);
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
g = png_reciprocal(png_ptr->background_gamma);
gs = png_reciprocal2(png_ptr->background_gamma,
- png_ptr->screen_gamma);
+ png_ptr->screen_gamma);
break;
default:
g = PNG_FP_1; /* back_1 */
@@ -1735,7 +1626,7 @@ png_init_read_transformations(png_structrp png_ptr)
break;
}
- if (png_gamma_significant(gs) != 0)
+ if (png_gamma_significant(gs))
{
back.red = png_gamma_8bit_correct(png_ptr->background.red,
gs);
@@ -1752,14 +1643,14 @@ png_init_read_transformations(png_structrp png_ptr)
back.blue = (png_byte)png_ptr->background.blue;
}
- if (png_gamma_significant(g) != 0)
+ if (png_gamma_significant(g))
{
back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
- g);
+ g);
back_1.green = png_gamma_8bit_correct(
- png_ptr->background.green, g);
+ png_ptr->background.green, g);
back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
- g);
+ g);
}
else
@@ -1781,51 +1672,19 @@ png_init_read_transformations(png_structrp png_ptr)
}
else /* if (png_ptr->trans_alpha[i] != 0xff) */
{
- if ((png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0)
- {
- /* Premultiply only:
- * component = round((component * alpha) / 255)
- */
- png_uint_32 component;
+ png_byte v, w;
- component = png_ptr->gamma_to_1[palette[i].red];
- component =
- (component * png_ptr->trans_alpha[i] + 128) / 255;
- palette[i].red = png_ptr->gamma_from_1[component];
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
- component = png_ptr->gamma_to_1[palette[i].green];
- component =
- (component * png_ptr->trans_alpha[i] + 128) / 255;
- palette[i].green = png_ptr->gamma_from_1[component];
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
- component = png_ptr->gamma_to_1[palette[i].blue];
- component =
- (component * png_ptr->trans_alpha[i] + 128) / 255;
- palette[i].blue = png_ptr->gamma_from_1[component];
- }
- else
- {
- /* Composite with background color:
- * component =
- * alpha * component + (1 - alpha) * background
- */
- png_byte v, w;
-
- v = png_ptr->gamma_to_1[palette[i].red];
- png_composite(w, v,
- png_ptr->trans_alpha[i], back_1.red);
- palette[i].red = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].green];
- png_composite(w, v,
- png_ptr->trans_alpha[i], back_1.green);
- palette[i].green = png_ptr->gamma_from_1[w];
-
- v = png_ptr->gamma_to_1[palette[i].blue];
- png_composite(w, v,
- png_ptr->trans_alpha[i], back_1.blue);
- palette[i].blue = png_ptr->gamma_from_1[w];
- }
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
}
}
else
@@ -1843,7 +1702,6 @@ png_init_read_transformations(png_structrp png_ptr)
* transformations elsewhere.
*/
png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
- png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
} /* color_type == PNG_COLOR_TYPE_PALETTE */
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
@@ -1861,9 +1719,9 @@ png_init_read_transformations(png_structrp png_ptr)
break;
case PNG_BACKGROUND_GAMMA_FILE:
- g = png_reciprocal(png_ptr->file_gamma);
- gs = png_reciprocal2(png_ptr->file_gamma,
- png_ptr->screen_gamma);
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
@@ -1879,11 +1737,11 @@ png_init_read_transformations(png_structrp png_ptr)
g_sig = png_gamma_significant(g);
gs_sig = png_gamma_significant(gs);
- if (g_sig != 0)
+ if (g_sig)
png_ptr->background_1.gray = png_gamma_correct(png_ptr,
png_ptr->background.gray, g);
- if (gs_sig != 0)
+ if (gs_sig)
png_ptr->background.gray = png_gamma_correct(png_ptr,
png_ptr->background.gray, gs);
@@ -1892,7 +1750,7 @@ png_init_read_transformations(png_structrp png_ptr)
(png_ptr->background.red != png_ptr->background.gray))
{
/* RGB or RGBA with color background */
- if (g_sig != 0)
+ if (g_sig)
{
png_ptr->background_1.red = png_gamma_correct(png_ptr,
png_ptr->background.red, g);
@@ -1904,7 +1762,7 @@ png_init_read_transformations(png_structrp png_ptr)
png_ptr->background.blue, g);
}
- if (gs_sig != 0)
+ if (gs_sig)
{
png_ptr->background.red = png_gamma_correct(png_ptr,
png_ptr->background.red, gs);
@@ -1934,7 +1792,7 @@ png_init_read_transformations(png_structrp png_ptr)
else
/* Transformation does not include PNG_BACKGROUND */
-#endif /* READ_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
/* RGB_TO_GRAY needs to have non-gamma-corrected values! */
@@ -1964,11 +1822,11 @@ png_init_read_transformations(png_structrp png_ptr)
#ifdef PNG_READ_BACKGROUND_SUPPORTED
else
#endif
-#endif /* READ_GAMMA */
+#endif /* PNG_READ_GAMMA_SUPPORTED */
#ifdef PNG_READ_BACKGROUND_SUPPORTED
/* No GAMMA transformation (see the hanging else 4 lines above) */
- if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ if ((png_ptr->transformations & PNG_COMPOSE) &&
(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
{
int i;
@@ -2003,11 +1861,11 @@ png_init_read_transformations(png_structrp png_ptr)
png_ptr->transformations &= ~PNG_COMPOSE;
}
-#endif /* READ_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
#ifdef PNG_READ_SHIFT_SUPPORTED
- if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
- (png_ptr->transformations & PNG_EXPAND) == 0 &&
+ if ((png_ptr->transformations & PNG_SHIFT) &&
+ !(png_ptr->transformations & PNG_EXPAND) &&
(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
{
int i;
@@ -2016,40 +1874,37 @@ png_init_read_transformations(png_structrp png_ptr)
png_ptr->transformations &= ~PNG_SHIFT;
- /* significant bits can be in the range 1 to 7 for a meaningful result, if
+ /* significant bits can be in the range 1 to 7 for a meaninful result, if
* the number of significant bits is 0 then no shift is done (this is an
* error condition which is silently ignored.)
*/
- if (shift > 0 && shift < 8)
- for (i=0; ipalette[i].red;
+ if (shift > 0 && shift < 8) for (i=0; ipalette[i].red;
- component >>= shift;
- png_ptr->palette[i].red = (png_byte)component;
- }
+ component >>= shift;
+ png_ptr->palette[i].red = (png_byte)component;
+ }
shift = 8 - png_ptr->sig_bit.green;
- if (shift > 0 && shift < 8)
- for (i=0; ipalette[i].green;
+ if (shift > 0 && shift < 8) for (i=0; ipalette[i].green;
- component >>= shift;
- png_ptr->palette[i].green = (png_byte)component;
- }
+ component >>= shift;
+ png_ptr->palette[i].green = (png_byte)component;
+ }
shift = 8 - png_ptr->sig_bit.blue;
- if (shift > 0 && shift < 8)
- for (i=0; ipalette[i].blue;
+ if (shift > 0 && shift < 8) for (i=0; ipalette[i].blue;
- component >>= shift;
- png_ptr->palette[i].blue = (png_byte)component;
- }
+ component >>= shift;
+ png_ptr->palette[i].blue = (png_byte)component;
+ }
}
-#endif /* READ_SHIFT */
+#endif /* PNG_READ_SHIFT_SUPPORTED */
}
/* Modify the info structure to reflect the transformations. The
@@ -2062,7 +1917,7 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
png_debug(1, "in png_read_transform_info");
#ifdef PNG_READ_EXPAND_SUPPORTED
- if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ if (png_ptr->transformations & PNG_EXPAND)
{
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
@@ -2078,15 +1933,12 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
info_ptr->bit_depth = 8;
info_ptr->num_trans = 0;
-
- if (png_ptr->palette == NULL)
- png_error (png_ptr, "Palette is NULL in indexed image");
}
else
{
- if (png_ptr->num_trans != 0)
+ if (png_ptr->num_trans)
{
- if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
+ if (png_ptr->transformations & PNG_EXPAND_tRNS)
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
}
if (info_ptr->bit_depth < 8)
@@ -2102,7 +1954,7 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
/* The following is almost certainly wrong unless the background value is in
* the screen space!
*/
- if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ if (png_ptr->transformations & PNG_COMPOSE)
info_ptr->background = png_ptr->background;
#endif
@@ -2112,28 +1964,28 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
* been called before this from png_read_update_info->png_read_start_row
* sometimes does the gamma transform and cancels the flag.
*
- * TODO: this is confusing. It only changes the result of png_get_gAMA and,
- * yes, it does return the value that the transformed data effectively has
- * but does any app really understand this?
+ * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
+ * the screen_gamma value. The following probably results in weirdness if
+ * the info_ptr is used by the app after the rows have been read.
*/
- info_ptr->gamma = png_ptr->file_gamma;
+ info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
#endif
if (info_ptr->bit_depth == 16)
{
# ifdef PNG_READ_16BIT_SUPPORTED
# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
+ if (png_ptr->transformations & PNG_SCALE_16_TO_8)
info_ptr->bit_depth = 8;
# endif
# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
- if ((png_ptr->transformations & PNG_16_TO_8) != 0)
+ if (png_ptr->transformations & PNG_16_TO_8)
info_ptr->bit_depth = 8;
# endif
# else
- /* No 16-bit support: force chopping 16-bit input down to 8, in this case
+ /* No 16 bit support: force chopping 16-bit input down to 8, in this case
* the app program can chose if both APIs are available by setting the
* correct scaling to use.
*/
@@ -2154,27 +2006,27 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
CONFIGURATION ERROR: you must enable at least one 16 to 8 method
# endif
# endif
-#endif /* !READ_16BIT */
+#endif /* !READ_16BIT_SUPPORTED */
}
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
info_ptr->color_type = (png_byte)(info_ptr->color_type |
PNG_COLOR_MASK_COLOR);
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
info_ptr->color_type = (png_byte)(info_ptr->color_type &
~PNG_COLOR_MASK_COLOR);
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
- if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
+ if (png_ptr->transformations & PNG_QUANTIZE)
{
if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
(info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
- png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
+ png_ptr->palette_lookup && info_ptr->bit_depth == 8)
{
info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
}
@@ -2182,31 +2034,29 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
#endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED
- if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
- info_ptr->bit_depth == 8 &&
- info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&
+ info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
{
info_ptr->bit_depth = 16;
}
#endif
#ifdef PNG_READ_PACK_SUPPORTED
- if ((png_ptr->transformations & PNG_PACK) != 0 &&
- (info_ptr->bit_depth < 8))
+ if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
info_ptr->bit_depth = 8;
#endif
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
info_ptr->channels = 1;
- else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
info_ptr->channels = 3;
else
info_ptr->channels = 1;
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
+ if (png_ptr->transformations & PNG_STRIP_ALPHA)
{
info_ptr->color_type = (png_byte)(info_ptr->color_type &
~PNG_COLOR_MASK_ALPHA);
@@ -2214,30 +2064,30 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
}
#endif
- if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
info_ptr->channels++;
#ifdef PNG_READ_FILLER_SUPPORTED
/* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
- if ((png_ptr->transformations & PNG_FILLER) != 0 &&
- (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
- info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
+ if ((png_ptr->transformations & PNG_FILLER) &&
+ ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
{
info_ptr->channels++;
/* If adding a true alpha channel not just filler */
- if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
+ if (png_ptr->transformations & PNG_ADD_ALPHA)
info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
}
#endif
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
- if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
{
- if (png_ptr->user_transform_depth != 0)
+ if (info_ptr->bit_depth < png_ptr->user_transform_depth)
info_ptr->bit_depth = png_ptr->user_transform_depth;
- if (png_ptr->user_transform_channels != 0)
+ if (info_ptr->channels < png_ptr->user_transform_channels)
info_ptr->channels = png_ptr->user_transform_channels;
}
#endif
@@ -2256,11 +2106,308 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
png_ptr->info_rowbytes = info_ptr->rowbytes;
#ifndef PNG_READ_EXPAND_SUPPORTED
- if (png_ptr != NULL)
+ if (png_ptr)
return;
#endif
}
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_read_transformations");
+
+ if (png_ptr->row_buf == NULL)
+ {
+ /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
+ * error is incredibly rare and incredibly easy to debug without this
+ * information.
+ */
+ png_error(png_ptr, "NULL row buffer");
+ }
+
+ /* The following is debugging; prior to 1.5.4 the code was never compiled in;
+ * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
+ * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for
+ * all transformations, however in practice the ROW_INIT always gets done on
+ * demand, if necessary.
+ */
+ if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
+ !(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ {
+ /* Application has failed to call either png_read_start_image() or
+ * png_read_update_info() after setting transforms that expand pixels.
+ * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
+ */
+ png_error(png_ptr, "Uninitialized row");
+ }
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+ }
+
+ else
+ {
+ if (png_ptr->num_trans &&
+ (png_ptr->transformations & PNG_EXPAND_tRNS))
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->trans_color));
+
+ else
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ !(png_ptr->transformations & PNG_COMPOSE) &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, row_info,
+ png_ptr->row_buf + 1);
+
+ if (rgb_error)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ * In most cases, the "simple transparency" should be done prior to doing
+ * gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ * pixel is transparent. You would also need to make sure that the
+ * transparency information is upgraded to RGB.
+ *
+ * To summarize, the current flow is:
+ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ * with background "in place" if transparent,
+ * convert to RGB if necessary
+ * - Gray + alpha -> composite with gray background and remove alpha bytes,
+ * convert to RGB if necessary
+ *
+ * To support RGB backgrounds for gray images we need:
+ * - Gray + simple transparency -> convert to RGB + simple transparency,
+ * compare 3 or 6 bytes and composite with
+ * background "in place" if transparent
+ * (3x compare/pixel compared to doing
+ * composite with gray bkgrnd)
+ * - Gray + alpha -> convert to RGB + alpha, composite with background and
+ * remove alpha bytes (3x float
+ * operations/pixel compared with composite
+ * on gray background)
+ *
+ * Greg's change will do this. The reason it wasn't done before is for
+ * performance, as this increases the per-pixel operations. If we would check
+ * in advance if the background was gray or RGB, and position the gray-to-RGB
+ * transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* If gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons
+ */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ if (png_ptr->transformations & PNG_COMPOSE)
+ png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if ((png_ptr->transformations & PNG_GAMMA) &&
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Because RGB_TO_GRAY does the gamma transform. */
+ !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ /* Because PNG_COMPOSE does the gamma transform if there is something to
+ * do (if there is an alpha channel or transparency.)
+ */
+ !((png_ptr->transformations & PNG_COMPOSE) &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+ /* Because png_init_read_transformations transforms the palette, unless
+ * RGB_TO_GRAY will do the transform.
+ */
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA))
+ png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if (png_ptr->transformations & PNG_SCALE_16_TO_8)
+ png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* There is no harm in doing both of these because only one has any effect,
+ * by putting the 'scale' option first if the app asks for scale (either by
+ * calling the API or in a TRANSFORM flag) this is what happens.
+ */
+ if (png_ptr->transformations & PNG_16_TO_8)
+ png_do_chop(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ if (png_ptr->transformations & PNG_QUANTIZE)
+ {
+ png_do_quantize(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->quantize_index);
+
+ if (row_info->rowbytes == 0)
+ png_error(png_ptr, "png_do_quantize returned rowbytes=0");
+ }
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ /* Do the expansion now, after all the arithmetic has been done. Notice
+ * that previous transformations can handle the PNG_EXPAND_16 flag if this
+ * is efficient (particularly true in the case of gamma correction, where
+ * better accuracy results faster!)
+ */
+ if (png_ptr->transformations & PNG_EXPAND_16)
+ png_do_expand_16(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* NOTE: moved here in 1.5.4 (from much later in this list.) */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_unshift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_unpack(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Added at libpng-1.5.10 */
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max >= 0)
+ png_do_check_palette_indexes(png_ptr, row_info);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_read_filler(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+#ifdef PNG_READ_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if (png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ if (png_ptr->user_transform_depth)
+ row_info->bit_depth = png_ptr->user_transform_depth;
+
+ if (png_ptr->user_transform_channels)
+ row_info->channels = png_ptr->user_transform_channels;
+#endif
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth *
+ row_info->channels);
+
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
+ }
+#endif
+}
+
#ifdef PNG_READ_PACK_SUPPORTED
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
* without changing the actual values. Thus, if you had a row with
@@ -2268,7 +2415,7 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
* the numbers 0 or 1. If you would rather they contain 0 and 255, use
* png_do_shift() after this.
*/
-static void
+void /* PRIVATE */
png_do_unpack(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_unpack");
@@ -2282,9 +2429,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
{
case 1:
{
- png_bytep sp = row + (size_t)((row_width - 1) >> 3);
- png_bytep dp = row + (size_t)row_width - 1;
- png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x01);
@@ -2306,9 +2453,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
case 2:
{
- png_bytep sp = row + (size_t)((row_width - 1) >> 2);
- png_bytep dp = row + (size_t)row_width - 1;
- png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x03);
@@ -2329,9 +2476,9 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
case 4:
{
- png_bytep sp = row + (size_t)((row_width - 1) >> 1);
- png_bytep dp = row + (size_t)row_width - 1;
- png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x0f);
@@ -2366,7 +2513,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
* a row of bit depth 8, but only 5 are significant, this will shift
* the values back to 0 through 31.
*/
-static void
+void /* PRIVATE */
png_do_unshift(png_row_infop row_info, png_bytep row,
png_const_color_8p sig_bits)
{
@@ -2383,7 +2530,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row,
int channels = 0;
int bit_depth = row_info->bit_depth;
- if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (color_type & PNG_COLOR_MASK_COLOR)
{
shift[channels++] = bit_depth - sig_bits->red;
shift[channels++] = bit_depth - sig_bits->green;
@@ -2395,7 +2542,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row,
shift[channels++] = bit_depth - sig_bits->gray;
}
- if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (color_type & PNG_COLOR_MASK_ALPHA)
{
shift[channels++] = bit_depth - sig_bits->alpha;
}
@@ -2415,7 +2562,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row,
have_shift = 1;
}
- if (have_shift == 0)
+ if (!have_shift)
return;
}
@@ -2493,7 +2640,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row,
if (++channel >= channels)
channel = 0;
*bp++ = (png_byte)(value >> 8);
- *bp++ = (png_byte)value;
+ *bp++ = (png_byte)(value & 0xff);
}
break;
}
@@ -2505,7 +2652,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row,
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
/* Scale rows of bit depth 16 down to 8 accurately */
-static void
+void /* PRIVATE */
png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_scale_16_to_8");
@@ -2518,8 +2665,8 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
while (sp < ep)
{
- /* The input is an array of 16-bit components, these must be scaled to
- * 8 bits each. For a 16-bit value V the required value (from the PNG
+ /* The input is an array of 16 bit components, these must be scaled to
+ * 8 bits each. For a 16 bit value V the required value (from the PNG
* specification) is:
*
* (V * 255) / 65535
@@ -2540,7 +2687,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
*
* The approximate differs from the exact answer only when (vlo-vhi) is
* 128; it then gives a correction of +1 when the exact correction is
- * 0. This gives 128 errors. The exact answer (correct for all 16-bit
+ * 0. This gives 128 errors. The exact answer (correct for all 16 bit
* input values) is:
*
* error = (vlo-vhi+128)*65535 >> 24;
@@ -2563,7 +2710,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
#endif
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
-static void
+void /* PRIVATE */
/* Simply discard the low byte. This was the default behavior prior
* to libpng-1.5.4.
*/
@@ -2591,103 +2738,104 @@ png_do_chop(png_row_infop row_info, png_bytep row)
#endif
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
-static void
+void /* PRIVATE */
png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
{
- png_uint_32 row_width = row_info->width;
-
png_debug(1, "in png_do_read_swap_alpha");
- if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
- /* This converts from RGBA to ARGB */
- if (row_info->bit_depth == 8)
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
{
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
}
- }
#ifdef PNG_READ_16BIT_SUPPORTED
- /* This converts from RRGGBBAA to AARRGGBB */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
{
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
}
- }
#endif
- }
-
- else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- {
- /* This converts from GA to AG */
- if (row_info->bit_depth == 8)
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save;
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
- {
- save = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save;
- }
}
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+
#ifdef PNG_READ_16BIT_SUPPORTED
- /* This converts from GGAA to AAGG */
- else
- {
- png_bytep sp = row + row_info->rowbytes;
- png_bytep dp = sp;
- png_byte save[2];
- png_uint_32 i;
-
- for (i = 0; i < row_width; i++)
+ /* This converts from GGAA to AAGG */
+ else
{
- save[0] = *(--sp);
- save[1] = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = *(--sp);
- *(--dp) = save[0];
- *(--dp) = save[1];
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
}
- }
#endif
+ }
}
}
#endif
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
-static void
+void /* PRIVATE */
png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_uint_32 row_width;
@@ -2789,7 +2937,7 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
#ifdef PNG_READ_FILLER_SUPPORTED
/* Add filler channel if we have RGB color */
-static void
+void /* PRIVATE */
png_do_read_filler(png_row_infop row_info, png_bytep row,
png_uint_32 filler, png_uint_32 flags)
{
@@ -2797,9 +2945,9 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
png_uint_32 row_width = row_info->width;
#ifdef PNG_READ_16BIT_SUPPORTED
- png_byte hi_filler = (png_byte)(filler>>8);
+ png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
#endif
- png_byte lo_filler = (png_byte)filler;
+ png_byte lo_filler = (png_byte)(filler & 0xff);
png_debug(1, "in png_do_read_filler");
@@ -2808,11 +2956,11 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
{
if (row_info->bit_depth == 8)
{
- if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This changes the data from G to GX */
- png_bytep sp = row + (size_t)row_width;
- png_bytep dp = sp + (size_t)row_width;
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
for (i = 1; i < row_width; i++)
{
*(--dp) = lo_filler;
@@ -2827,8 +2975,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
else
{
/* This changes the data from G to XG */
- png_bytep sp = row + (size_t)row_width;
- png_bytep dp = sp + (size_t)row_width;
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
for (i = 0; i < row_width; i++)
{
*(--dp) = *(--sp);
@@ -2843,20 +2991,20 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
#ifdef PNG_READ_16BIT_SUPPORTED
else if (row_info->bit_depth == 16)
{
- if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This changes the data from GG to GGXX */
- png_bytep sp = row + (size_t)row_width * 2;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 1; i < row_width; i++)
{
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
*(--dp) = *(--sp);
*(--dp) = *(--sp);
}
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
row_info->channels = 2;
row_info->pixel_depth = 32;
row_info->rowbytes = row_width * 4;
@@ -2865,14 +3013,14 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
else
{
/* This changes the data from GG to XXGG */
- png_bytep sp = row + (size_t)row_width * 2;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++)
{
*(--dp) = *(--sp);
*(--dp) = *(--sp);
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
}
row_info->channels = 2;
row_info->pixel_depth = 32;
@@ -2885,11 +3033,11 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
{
if (row_info->bit_depth == 8)
{
- if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This changes the data from RGB to RGBX */
- png_bytep sp = row + (size_t)row_width * 3;
- png_bytep dp = sp + (size_t)row_width;
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
for (i = 1; i < row_width; i++)
{
*(--dp) = lo_filler;
@@ -2906,8 +3054,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
else
{
/* This changes the data from RGB to XRGB */
- png_bytep sp = row + (size_t)row_width * 3;
- png_bytep dp = sp + (size_t)row_width;
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
for (i = 0; i < row_width; i++)
{
*(--dp) = *(--sp);
@@ -2924,15 +3072,15 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
#ifdef PNG_READ_16BIT_SUPPORTED
else if (row_info->bit_depth == 16)
{
- if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This changes the data from RRGGBB to RRGGBBXX */
- png_bytep sp = row + (size_t)row_width * 6;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 1; i < row_width; i++)
{
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
*(--dp) = *(--sp);
*(--dp) = *(--sp);
*(--dp) = *(--sp);
@@ -2940,8 +3088,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
*(--dp) = *(--sp);
*(--dp) = *(--sp);
}
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
row_info->channels = 4;
row_info->pixel_depth = 64;
row_info->rowbytes = row_width * 8;
@@ -2950,8 +3098,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
else
{
/* This changes the data from RRGGBB to XXRRGGBB */
- png_bytep sp = row + (size_t)row_width * 6;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++)
{
*(--dp) = *(--sp);
@@ -2960,8 +3108,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
*(--dp) = *(--sp);
*(--dp) = *(--sp);
*(--dp) = *(--sp);
- *(--dp) = lo_filler;
*(--dp) = hi_filler;
+ *(--dp) = lo_filler;
}
row_info->channels = 4;
@@ -2976,7 +3124,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row,
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
/* Expand grayscale files to RGB, with or without alpha */
-static void
+void /* PRIVATE */
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
{
png_uint_32 i;
@@ -2985,15 +3133,15 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
png_debug(1, "in png_do_gray_to_rgb");
if (row_info->bit_depth >= 8 &&
- (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ !(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
if (row_info->bit_depth == 8)
{
/* This changes G to RGB */
- png_bytep sp = row + (size_t)row_width - 1;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++)
{
*(dp--) = *sp;
@@ -3005,8 +3153,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
else
{
/* This changes GG to RRGGBB */
- png_bytep sp = row + (size_t)row_width * 2 - 1;
- png_bytep dp = sp + (size_t)row_width * 4;
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
for (i = 0; i < row_width; i++)
{
*(dp--) = *sp;
@@ -3024,8 +3172,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
if (row_info->bit_depth == 8)
{
/* This changes GA to RGBA */
- png_bytep sp = row + (size_t)row_width * 2 - 1;
- png_bytep dp = sp + (size_t)row_width * 2;
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
for (i = 0; i < row_width; i++)
{
*(dp--) = *(sp--);
@@ -3038,8 +3186,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
else
{
/* This changes GGAA to RRGGBBAA */
- png_bytep sp = row + (size_t)row_width * 4 - 1;
- png_bytep dp = sp + (size_t)row_width * 4;
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
for (i = 0; i < row_width; i++)
{
*(dp--) = *(sp--);
@@ -3067,7 +3215,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
* using the equation given in Poynton's ColorFAQ of 1998-01-04 at
* (THIS LINK IS DEAD June 2008 but
* versions dated 1998 through November 2002 have been archived at
- * https://web.archive.org/web/20000816232553/www.inforamp.net/
+ * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
* Charles Poynton poynton at poynton.com
*
@@ -3110,26 +3258,28 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
* values this results in an implicit assumption that the original PNG RGB
* values were linear.
*
- * Other integer coefficients can be used via png_set_rgb_to_gray(). Because
+ * Other integer coefficents can be used via png_set_rgb_to_gray(). Because
* the API takes just red and green coefficients the blue coefficient is
* calculated to make the sum 32768. This will result in different rounding
* to that used above.
*/
-static int
+int /* PRIVATE */
png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
+
{
int rgb_error = 0;
png_debug(1, "in png_do_rgb_to_gray");
- if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
- (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
{
- png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
- png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
- png_uint_32 bc = 32768 - rc - gc;
- png_uint_32 row_width = row_info->width;
- int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+ PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ PNG_CONST png_uint_32 bc = 32768 - rc - gc;
+ PNG_CONST png_uint_32 row_width = row_info->width;
+ PNG_CONST int have_alpha =
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
if (row_info->bit_depth == 8)
{
@@ -3173,7 +3323,7 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
*(dp++) = red;
}
- if (have_alpha != 0)
+ if (have_alpha)
*(dp++) = *(sp++);
}
}
@@ -3202,7 +3352,7 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
else
*(dp++) = red;
- if (have_alpha != 0)
+ if (have_alpha)
*(dp++) = *(sp++);
}
}
@@ -3220,17 +3370,16 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
for (i = 0; i < row_width; i++)
{
png_uint_16 red, green, blue, w;
- png_byte hi,lo;
- hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
- hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
- hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
+ red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red == green && red == blue)
{
if (png_ptr->gamma_16_table != NULL)
- w = png_ptr->gamma_16_table[(red & 0xff)
- >> png_ptr->gamma_shift][red >> 8];
+ w = png_ptr->gamma_16_table[(red&0xff)
+ >> png_ptr->gamma_shift][red>>8];
else
w = red;
@@ -3238,16 +3387,16 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
else
{
- png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff)
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff)
>> png_ptr->gamma_shift][red>>8];
png_uint_16 green_1 =
- png_ptr->gamma_16_to_1[(green & 0xff) >>
+ png_ptr->gamma_16_to_1[(green&0xff) >>
png_ptr->gamma_shift][green>>8];
- png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff)
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff)
>> png_ptr->gamma_shift][blue>>8];
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ bc*blue_1 + 16384)>>15);
- w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
png_ptr->gamma_shift][gray16 >> 8];
rgb_error |= 1;
}
@@ -3255,7 +3404,7 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)((w>>8) & 0xff);
*(dp++) = (png_byte)(w & 0xff);
- if (have_alpha != 0)
+ if (have_alpha)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
@@ -3272,25 +3421,24 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
for (i = 0; i < row_width; i++)
{
png_uint_16 red, green, blue, gray16;
- png_byte hi,lo;
- hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
- hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
- hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
+ red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red != green || red != blue)
rgb_error |= 1;
- /* From 1.5.5 in the 16-bit case do the accurate conversion even
+ /* From 1.5.5 in the 16 bit case do the accurate conversion even
* in the 'fast' case - this is because this is where the code
- * ends up when handling linear 16-bit data.
+ * ends up when handling linear 16 bit data.
*/
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
15);
- *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
*(dp++) = (png_byte)(gray16 & 0xff);
- if (have_alpha != 0)
+ if (have_alpha)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
@@ -3309,14 +3457,73 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
return rgb_error;
}
#endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code. This API is not used internally.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette");
+
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)v;
+ palette[i].green = (png_byte)v;
+ palette[i].blue = (png_byte)v;
+ }
+}
+#endif
+
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
/* Replace any alpha or transparency with the supplied background color.
* "background" is already in the screen gamma, while "background_1" is
* at a gamma of 1.0. Paletted files have already been taken care of.
*/
-static void
+void /* PRIVATE */
png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
{
#ifdef PNG_READ_GAMMA_SUPPORTED
@@ -3337,229 +3544,414 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
png_debug(1, "in png_do_compose");
- switch (row_info->color_type)
{
- case PNG_COLOR_TYPE_GRAY:
+ switch (row_info->color_type)
{
- switch (row_info->bit_depth)
+ case PNG_COLOR_TYPE_GRAY:
{
- case 1:
+ switch (row_info->bit_depth)
{
- sp = row;
- shift = 7;
- for (i = 0; i < row_width; i++)
+ case 1:
{
- if ((png_uint_16)((*sp >> shift) & 0x01)
- == png_ptr->trans_color.gray)
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
{
- unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
- tmp |=
- (unsigned int)(png_ptr->background.gray << shift);
- *sp = (png_byte)(tmp & 0xff);
- }
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
- if (shift == 0)
+ if (!shift)
+ {
+ shift = 7;
+ sp++;
+ }
+
+ else
+ shift--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
{
- shift = 7;
- sp++;
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x03;
+ unsigned int g = (gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03;
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= g << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+
+ else
+ shift -= 2;
+ }
}
else
- shift--;
- }
- break;
- }
-
- case 2:
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
- {
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == png_ptr->trans_color.gray)
- {
- unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
- tmp |=
- (unsigned int)png_ptr->background.gray << shift;
- *sp = (png_byte)(tmp & 0xff);
- }
-
- else
- {
- unsigned int p = (*sp >> shift) & 0x03;
- unsigned int g = (gamma_table [p | (p << 2) |
- (p << 4) | (p << 6)] >> 6) & 0x03;
- unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
- tmp |= (unsigned int)(g << shift);
- *sp = (png_byte)(tmp & 0xff);
- }
-
- if (shift == 0)
- {
- shift = 6;
- sp++;
- }
-
- else
- shift -= 2;
- }
- }
-
- else
#endif
- {
- sp = row;
- shift = 6;
- for (i = 0; i < row_width; i++)
{
- if ((png_uint_16)((*sp >> shift) & 0x03)
- == png_ptr->trans_color.gray)
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
{
- unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
- tmp |=
- (unsigned int)png_ptr->background.gray << shift;
- *sp = (png_byte)(tmp & 0xff);
- }
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
- if (shift == 0)
- {
- shift = 6;
- sp++;
- }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
- else
- shift -= 2;
+ else
+ shift -= 2;
+ }
}
+ break;
}
- break;
- }
- case 4:
- {
+ case 4:
+ {
#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_table != NULL)
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
+ if (gamma_table != NULL)
{
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == png_ptr->trans_color.gray)
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
{
- unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
- tmp |=
- (unsigned int)(png_ptr->background.gray << shift);
- *sp = (png_byte)(tmp & 0xff);
- }
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
- else
- {
- unsigned int p = (*sp >> shift) & 0x0f;
- unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
- 0x0f;
- unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
- tmp |= (unsigned int)(g << shift);
- *sp = (png_byte)(tmp & 0xff);
- }
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x0f;
+ unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
+ 0x0f;
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= g << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
- if (shift == 0)
- {
- shift = 4;
- sp++;
- }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
- else
- shift -= 4;
+ else
+ shift -= 4;
+ }
}
- }
- else
+ else
#endif
- {
- sp = row;
- shift = 4;
- for (i = 0; i < row_width; i++)
{
- if ((png_uint_16)((*sp >> shift) & 0x0f)
- == png_ptr->trans_color.gray)
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
{
- unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
- tmp |=
- (unsigned int)(png_ptr->background.gray << shift);
- *sp = (png_byte)(tmp & 0xff);
- }
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
- if (shift == 0)
- {
- shift = 4;
- sp++;
- }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
- else
- shift -= 4;
+ else
+ shift -= 4;
+ }
}
+ break;
}
- break;
- }
- case 8:
+ case 8:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+
+ else
+ *sp = gamma_table[*sp];
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+ }
+ break;
+ }
+
+ case 16:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
{
#ifdef PNG_READ_GAMMA_SUPPORTED
if (gamma_table != NULL)
{
sp = row;
- for (i = 0; i < row_width; i++, sp++)
+ for (i = 0; i < row_width; i++, sp += 3)
{
- if (*sp == png_ptr->trans_color.gray)
- *sp = (png_byte)png_ptr->background.gray;
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
else
+ {
*sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
}
}
else
#endif
{
sp = row;
- for (i = 0; i < row_width; i++, sp++)
+ for (i = 0; i < row_width; i++, sp += 3)
{
- if (*sp == png_ptr->trans_color.gray)
- *sp = (png_byte)png_ptr->background.gray;
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
}
}
- break;
}
-
- case 16:
+ else /* if (row_info->bit_depth == 16) */
{
#ifdef PNG_READ_GAMMA_SUPPORTED
if (gamma_16 != NULL)
{
sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
+ for (i = 0; i < row_width; i++, sp += 6)
{
- png_uint_16 v;
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
- if (v == png_ptr->trans_color.gray)
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
{
/* Background is already in screen gamma */
- *sp = (png_byte)((png_ptr->background.gray >> 8)
- & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.gray
- & 0xff);
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
}
else
{
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
*sp = (png_byte)((v >> 8) & 0xff);
*(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ *sp = gamma_table[*sp];
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.gray);
+ if (!optimize)
+ w = gamma_from_1[w];
+ *sp = w;
}
}
}
@@ -3569,489 +3961,300 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
sp = row;
for (i = 0; i < row_width; i++, sp += 2)
{
- png_uint_16 v;
+ png_byte a = *(sp + 1);
- v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (a == 0)
+ *sp = (png_byte)png_ptr->background.gray;
- if (v == png_ptr->trans_color.gray)
+ else if (a < 0xff)
+ png_composite(*sp, *sp, a, png_ptr->background.gray);
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ if (a == (png_uint_16)0xffff)
{
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
*sp = (png_byte)((png_ptr->background.gray >> 8)
- & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.gray
- & 0xff);
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, png_ptr->background_1.gray);
+ if (optimize)
+ w = v;
+ else
+ w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
}
}
}
- break;
- }
-
- default:
- break;
- }
- break;
- }
-
- case PNG_COLOR_TYPE_RGB:
- {
- if (row_info->bit_depth == 8)
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
- {
- if (*sp == png_ptr->trans_color.red &&
- *(sp + 1) == png_ptr->trans_color.green &&
- *(sp + 2) == png_ptr->trans_color.blue)
- {
- *sp = (png_byte)png_ptr->background.red;
- *(sp + 1) = (png_byte)png_ptr->background.green;
- *(sp + 2) = (png_byte)png_ptr->background.blue;
- }
-
- else
- {
- *sp = gamma_table[*sp];
- *(sp + 1) = gamma_table[*(sp + 1)];
- *(sp + 2) = gamma_table[*(sp + 2)];
- }
- }
- }
- else
+ else
#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 3)
{
- if (*sp == png_ptr->trans_color.red &&
- *(sp + 1) == png_ptr->trans_color.green &&
- *(sp + 2) == png_ptr->trans_color.blue)
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
{
- *sp = (png_byte)png_ptr->background.red;
- *(sp + 1) = (png_byte)png_ptr->background.green;
- *(sp + 2) = (png_byte)png_ptr->background.blue;
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_16 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
- png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
-
- png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
- + *(sp + 5));
-
- if (r == png_ptr->trans_color.red &&
- g == png_ptr->trans_color.green &&
- b == png_ptr->trans_color.blue)
- {
- /* Background is already in screen gamma */
- *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
- & 0xff);
- *(sp + 3) = (png_byte)(png_ptr->background.green
- & 0xff);
- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
- & 0xff);
- *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
- }
-
- else
- {
- png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
-
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
-
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
- }
- }
- }
-
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 6)
- {
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
-
- png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
-
- png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
- + *(sp + 5));
-
- if (r == png_ptr->trans_color.red &&
- g == png_ptr->trans_color.green &&
- b == png_ptr->trans_color.blue)
- {
- *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
- & 0xff);
- *(sp + 3) = (png_byte)(png_ptr->background.green
- & 0xff);
- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
- & 0xff);
- *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
- }
- }
- }
- }
- break;
- }
-
- case PNG_COLOR_TYPE_GRAY_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_uint_16 a = *(sp + 1);
-
- if (a == 0xff)
- *sp = gamma_table[*sp];
-
- else if (a == 0)
- {
- /* Background is already in screen gamma */
- *sp = (png_byte)png_ptr->background.gray;
- }
-
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, png_ptr->background_1.gray);
- if (optimize == 0)
- w = gamma_from_1[w];
- *sp = w;
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 2)
- {
- png_byte a = *(sp + 1);
-
- if (a == 0)
- *sp = (png_byte)png_ptr->background.gray;
-
- else if (a < 0xff)
- png_composite(*sp, *sp, a, png_ptr->background.gray);
- }
- }
- }
- else /* if (png_ptr->bit_depth == 16) */
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 4)
- {
- png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
-
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- }
-
- else if (a == 0)
- {
- /* Background is already in screen gamma */
- *sp = (png_byte)((png_ptr->background.gray >> 8)
- & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
- }
-
- else
- {
- png_uint_16 g, v, w;
-
- g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(v, g, a, png_ptr->background_1.gray);
- if (optimize != 0)
- w = v;
- else
- w = gamma_16_from_1[(v & 0xff) >>
- gamma_shift][v >> 8];
- *sp = (png_byte)((w >> 8) & 0xff);
- *(sp + 1) = (png_byte)(w & 0xff);
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 4)
- {
- png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
- + *(sp + 3));
-
- if (a == 0)
- {
- *sp = (png_byte)((png_ptr->background.gray >> 8)
- & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
- }
-
- else if (a < 0xffff)
- {
- png_uint_16 g, v;
-
- g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_composite_16(v, g, a, png_ptr->background.gray);
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
- }
- }
- }
- }
- break;
- }
-
- case PNG_COLOR_TYPE_RGB_ALPHA:
- {
- if (row_info->bit_depth == 8)
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
- gamma_table != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 4)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0xff)
- {
- *sp = gamma_table[*sp];
- *(sp + 1) = gamma_table[*(sp + 1)];
- *(sp + 2) = gamma_table[*(sp + 2)];
- }
-
- else if (a == 0)
- {
- /* Background is already in screen gamma */
- *sp = (png_byte)png_ptr->background.red;
- *(sp + 1) = (png_byte)png_ptr->background.green;
- *(sp + 2) = (png_byte)png_ptr->background.blue;
- }
-
- else
- {
- png_byte v, w;
-
- v = gamma_to_1[*sp];
- png_composite(w, v, a, png_ptr->background_1.red);
- if (optimize == 0) w = gamma_from_1[w];
- *sp = w;
-
- v = gamma_to_1[*(sp + 1)];
- png_composite(w, v, a, png_ptr->background_1.green);
- if (optimize == 0) w = gamma_from_1[w];
- *(sp + 1) = w;
-
- v = gamma_to_1[*(sp + 2)];
- png_composite(w, v, a, png_ptr->background_1.blue);
- if (optimize == 0) w = gamma_from_1[w];
- *(sp + 2) = w;
- }
- }
- }
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 4)
- {
- png_byte a = *(sp + 3);
-
- if (a == 0)
- {
- *sp = (png_byte)png_ptr->background.red;
- *(sp + 1) = (png_byte)png_ptr->background.green;
- *(sp + 2) = (png_byte)png_ptr->background.blue;
- }
-
- else if (a < 0xff)
- {
- png_composite(*sp, *sp, a, png_ptr->background.red);
-
- png_composite(*(sp + 1), *(sp + 1), a,
- png_ptr->background.green);
-
- png_composite(*(sp + 2), *(sp + 2), a,
- png_ptr->background.blue);
- }
- }
- }
- }
- else /* if (row_info->bit_depth == 16) */
- {
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
- gamma_16_to_1 != NULL)
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 8)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
-
- if (a == (png_uint_16)0xffff)
- {
- png_uint_16 v;
-
- v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
-
- v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
-
- v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
- }
-
- else if (a == 0)
- {
- /* Background is already in screen gamma */
- *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
- & 0xff);
- *(sp + 3) = (png_byte)(png_ptr->background.green
- & 0xff);
- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
- & 0xff);
- *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
- }
-
- else
- {
- png_uint_16 v, w;
-
- v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
- png_composite_16(w, v, a, png_ptr->background_1.red);
- if (optimize == 0)
- w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
- 8];
- *sp = (png_byte)((w >> 8) & 0xff);
- *(sp + 1) = (png_byte)(w & 0xff);
-
- v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
- png_composite_16(w, v, a, png_ptr->background_1.green);
- if (optimize == 0)
- w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
- 8];
-
- *(sp + 2) = (png_byte)((w >> 8) & 0xff);
- *(sp + 3) = (png_byte)(w & 0xff);
-
- v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
- png_composite_16(w, v, a, png_ptr->background_1.blue);
- if (optimize == 0)
- w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
- 8];
-
- *(sp + 4) = (png_byte)((w >> 8) & 0xff);
- *(sp + 5) = (png_byte)(w & 0xff);
- }
- }
- }
-
- else
-#endif
- {
- sp = row;
- for (i = 0; i < row_width; i++, sp += 8)
- {
- png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
- << 8) + (png_uint_16)(*(sp + 7)));
-
- if (a == 0)
- {
- *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
- *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
- *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
- & 0xff);
- *(sp + 3) = (png_byte)(png_ptr->background.green
- & 0xff);
- *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
- & 0xff);
- *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
- }
-
- else if (a < 0xffff)
- {
- png_uint_16 v;
-
- png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
- png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ *(sp + 3));
- png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
- + *(sp + 5));
- png_composite_16(v, r, a, png_ptr->background.red);
- *sp = (png_byte)((v >> 8) & 0xff);
- *(sp + 1) = (png_byte)(v & 0xff);
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
- png_composite_16(v, g, a, png_ptr->background.green);
- *(sp + 2) = (png_byte)((v >> 8) & 0xff);
- *(sp + 3) = (png_byte)(v & 0xff);
+ else if (a < 0xffff)
+ {
+ png_uint_16 g, v;
- png_composite_16(v, b, a, png_ptr->background.blue);
- *(sp + 4) = (png_byte)((v >> 8) & 0xff);
- *(sp + 5) = (png_byte)(v & 0xff);
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, png_ptr->background.gray);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
}
}
}
+ break;
}
- break;
- }
- default:
- break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.red);
+ if (!optimize) w = gamma_from_1[w];
+ *sp = w;
+
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, png_ptr->background_1.green);
+ if (!optimize) w = gamma_from_1[w];
+ *(sp + 1) = w;
+
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, png_ptr->background_1.blue);
+ if (!optimize) w = gamma_from_1[w];
+ *(sp + 2) = w;
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else if (a < 0xff)
+ {
+ png_composite(*sp, *sp, a, png_ptr->background.red);
+
+ png_composite(*(sp + 1), *(sp + 1), a,
+ png_ptr->background.green);
+
+ png_composite(*(sp + 2), *(sp + 2), a,
+ png_ptr->background.blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 v, w;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, png_ptr->background_1.red);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, png_ptr->background_1.green);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 2) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, png_ptr->background_1.blue);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 4) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(w & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else if (a < 0xffff)
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, png_ptr->background.red);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, g, a, png_ptr->background.green);
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, b, a, png_ptr->background.blue);
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
}
}
-#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
#ifdef PNG_READ_GAMMA_SUPPORTED
/* Gamma correct the image, avoiding the alpha channel. Make sure
@@ -4060,7 +4263,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
* is 16, use gamma_16_table and gamma_shift. Build these with
* build_gamma_table().
*/
-static void
+void /* PRIVATE */
png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
{
png_const_bytep gamma_table = png_ptr->gamma_table;
@@ -4261,22 +4464,23 @@ png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
* linear.) Called only with color types that have an alpha channel. Needs the
* from_1 tables.
*/
-static void
+void /* PRIVATE */
png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
{
png_uint_32 row_width = row_info->width;
png_debug(1, "in png_do_encode_alpha");
- if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
if (row_info->bit_depth == 8)
{
- png_bytep table = png_ptr->gamma_from_1;
+ PNG_CONST png_bytep table = png_ptr->gamma_from_1;
if (table != NULL)
{
- int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
/* The alpha channel is the last component: */
row += step - 1;
@@ -4290,12 +4494,13 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
else if (row_info->bit_depth == 16)
{
- png_uint_16pp table = png_ptr->gamma_16_from_1;
- int gamma_shift = png_ptr->gamma_shift;
+ PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
+ PNG_CONST int gamma_shift = png_ptr->gamma_shift;
if (table != NULL)
{
- int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
/* The alpha channel is the last component: */
row += step - 2;
@@ -4325,10 +4530,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
/* Expands a palette row to an RGB or RGBA row depending
* upon whether you supply trans and num_trans.
*/
-static void
-png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
- png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha,
- int num_trans)
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
{
int shift, value;
png_bytep sp, dp;
@@ -4345,8 +4549,8 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
{
case 1:
{
- sp = row + (size_t)((row_width - 1) >> 3);
- dp = row + (size_t)row_width - 1;
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
shift = 7 - (int)((row_width + 7) & 0x07);
for (i = 0; i < row_width; i++)
{
@@ -4372,8 +4576,8 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
case 2:
{
- sp = row + (size_t)((row_width - 1) >> 2);
- dp = row + (size_t)row_width - 1;
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
for (i = 0; i < row_width; i++)
{
@@ -4395,8 +4599,8 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
case 4:
{
- sp = row + (size_t)((row_width - 1) >> 1);
- dp = row + (size_t)row_width - 1;
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
shift = (int)((row_width & 0x01) << 2);
for (i = 0; i < row_width; i++)
{
@@ -4429,30 +4633,17 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
{
if (num_trans > 0)
{
- sp = row + (size_t)row_width - 1;
- dp = row + ((size_t)row_width << 2) - 1;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
- i = 0;
-#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
- if (png_ptr->riffled_palette != NULL)
- {
- /* The RGBA optimization works with png_ptr->bit_depth == 8
- * but sometimes row_info->bit_depth has been changed to 8.
- * In these cases, the palette hasn't been riffled.
- */
- i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row,
- &sp, &dp);
- }
-#else
- PNG_UNUSED(png_ptr)
-#endif
-
- for (; i < row_width; i++)
+ for (i = 0; i < row_width; i++)
{
if ((int)(*sp) >= num_trans)
*dp-- = 0xff;
+
else
*dp-- = trans_alpha[*sp];
+
*dp-- = palette[*sp].blue;
*dp-- = palette[*sp].green;
*dp-- = palette[*sp].red;
@@ -4467,17 +4658,10 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
else
{
- sp = row + (size_t)row_width - 1;
- dp = row + (size_t)(row_width * 3) - 1;
- i = 0;
-#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
- i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row,
- &sp, &dp);
-#else
- PNG_UNUSED(png_ptr)
-#endif
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
- for (; i < row_width; i++)
+ for (i = 0; i < row_width; i++)
{
*dp-- = palette[*sp].blue;
*dp-- = palette[*sp].green;
@@ -4499,7 +4683,7 @@ png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info,
/* If the bit depth < 8, it is expanded to 8. Also, if the already
* expanded transparency value is supplied, an alpha channel is built.
*/
-static void
+void /* PRIVATE */
png_do_expand(png_row_infop row_info, png_bytep row,
png_const_color_16p trans_color)
{
@@ -4510,130 +4694,193 @@ png_do_expand(png_row_infop row_info, png_bytep row,
png_debug(1, "in png_do_expand");
- if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
- unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
-
- if (row_info->bit_depth < 8)
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
- switch (row_info->bit_depth)
+ unsigned int gray = trans_color ? trans_color->gray : 0;
+
+ if (row_info->bit_depth < 8)
{
- case 1:
+ switch (row_info->bit_depth)
{
- gray = (gray & 0x01) * 0xff;
- sp = row + (size_t)((row_width - 1) >> 3);
- dp = row + (size_t)row_width - 1;
- shift = 7 - (int)((row_width + 7) & 0x07);
- for (i = 0; i < row_width; i++)
+ case 1:
{
- if ((*sp >> shift) & 0x01)
- *dp = 0xff;
-
- else
- *dp = 0;
-
- if (shift == 7)
+ gray = (gray & 0x01) * 0xff;
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
{
- shift = 0;
- sp--;
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+
+ else
+ *dp = 0;
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
}
-
- else
- shift++;
-
- dp--;
+ break;
}
- break;
+
+ case 2:
+ {
+ gray = (gray & 0x03) * 0x55;
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ gray = (gray & 0x0f) * 0x11;
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
}
- case 2:
- {
- gray = (gray & 0x03) * 0x55;
- sp = row + (size_t)((row_width - 1) >> 2);
- dp = row + (size_t)row_width - 1;
- shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x03;
- *dp = (png_byte)(value | (value << 2) | (value << 4) |
- (value << 6));
- if (shift == 6)
- {
- shift = 0;
- sp--;
- }
-
- else
- shift += 2;
-
- dp--;
- }
- break;
- }
-
- case 4:
- {
- gray = (gray & 0x0f) * 0x11;
- sp = row + (size_t)((row_width - 1) >> 1);
- dp = row + (size_t)row_width - 1;
- shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
- for (i = 0; i < row_width; i++)
- {
- value = (*sp >> shift) & 0x0f;
- *dp = (png_byte)(value | (value << 4));
- if (shift == 4)
- {
- shift = 0;
- sp--;
- }
-
- else
- shift = 4;
-
- dp--;
- }
- break;
- }
-
- default:
- break;
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
}
- row_info->bit_depth = 8;
- row_info->pixel_depth = 8;
- row_info->rowbytes = row_width;
- }
+ if (trans_color != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ gray = gray & 0xff;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 1) - 1;
- if (trans_color != NULL)
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp == gray)
+ *dp-- = 0;
+
+ else
+ *dp-- = 0xff;
+
+ *dp-- = *sp--;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ unsigned int gray_high = (gray >> 8) & 0xff;
+ unsigned int gray_low = gray & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 1) == gray_high && *(sp) == gray_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_width);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)
{
if (row_info->bit_depth == 8)
{
- gray = gray & 0xff;
- sp = row + (size_t)row_width - 1;
- dp = row + ((size_t)row_width << 1) - 1;
-
+ png_byte red = (png_byte)(trans_color->red & 0xff);
+ png_byte green = (png_byte)(trans_color->green & 0xff);
+ png_byte blue = (png_byte)(trans_color->blue & 0xff);
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
for (i = 0; i < row_width; i++)
{
- if ((*sp & 0xffU) == gray)
+ if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
*dp-- = 0;
else
*dp-- = 0xff;
*dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
}
}
-
else if (row_info->bit_depth == 16)
{
- unsigned int gray_high = (gray >> 8) & 0xff;
- unsigned int gray_low = gray & 0xff;
+ png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
+ png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
+ png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
+ png_byte red_low = (png_byte)(trans_color->red & 0xff);
+ png_byte green_low = (png_byte)(trans_color->green & 0xff);
+ png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
sp = row + row_info->rowbytes - 1;
- dp = row + (row_info->rowbytes << 1) - 1;
+ dp = row + (png_size_t)(row_width << 3) - 1;
for (i = 0; i < row_width; i++)
{
- if ((*(sp - 1) & 0xffU) == gray_high &&
- (*(sp) & 0xffU) == gray_low)
+ if (*(sp - 5) == red_high &&
+ *(sp - 4) == red_low &&
+ *(sp - 3) == green_high &&
+ *(sp - 2) == green_low &&
+ *(sp - 1) == blue_high &&
+ *(sp ) == blue_low)
{
*dp-- = 0;
*dp-- = 0;
@@ -4647,81 +4894,18 @@ png_do_expand(png_row_infop row_info, png_bytep row,
*dp-- = *sp--;
*dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
}
}
-
- row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
- row_info->channels = 2;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
- row_width);
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
}
}
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
- trans_color != NULL)
- {
- if (row_info->bit_depth == 8)
- {
- png_byte red = (png_byte)(trans_color->red & 0xff);
- png_byte green = (png_byte)(trans_color->green & 0xff);
- png_byte blue = (png_byte)(trans_color->blue & 0xff);
- sp = row + (size_t)row_info->rowbytes - 1;
- dp = row + ((size_t)row_width << 2) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
- *dp-- = 0;
-
- else
- *dp-- = 0xff;
-
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- else if (row_info->bit_depth == 16)
- {
- png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
- png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
- png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
- png_byte red_low = (png_byte)(trans_color->red & 0xff);
- png_byte green_low = (png_byte)(trans_color->green & 0xff);
- png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
- sp = row + row_info->rowbytes - 1;
- dp = row + ((size_t)row_width << 3) - 1;
- for (i = 0; i < row_width; i++)
- {
- if (*(sp - 5) == red_high &&
- *(sp - 4) == red_low &&
- *(sp - 3) == green_high &&
- *(sp - 2) == green_low &&
- *(sp - 1) == blue_high &&
- *(sp ) == blue_low)
- {
- *dp-- = 0;
- *dp-- = 0;
- }
-
- else
- {
- *dp-- = 0xff;
- *dp-- = 0xff;
- }
-
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- *dp-- = *sp--;
- }
- }
- row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- row_info->channels = 4;
- row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
- }
}
#endif
@@ -4729,7 +4913,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
/* If the bit depth is 8 and the color type is not a palette type expand the
* whole row to 16 bits. Has no effect otherwise.
*/
-static void
+void /* PRIVATE */
png_do_expand_16(png_row_infop row_info, png_bytep row)
{
if (row_info->bit_depth == 8 &&
@@ -4747,9 +4931,7 @@ png_do_expand_16(png_row_infop row_info, png_bytep row)
png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
while (dp > sp)
- {
- dp[-2] = dp[-1] = *--sp; dp -= 2;
- }
+ dp[-2] = dp[-1] = *--sp, dp -= 2;
row_info->rowbytes *= 2;
row_info->bit_depth = 16;
@@ -4759,7 +4941,7 @@ png_do_expand_16(png_row_infop row_info, png_bytep row)
#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
-static void
+void /* PRIVATE */
png_do_quantize(png_row_infop row_info, png_bytep row,
png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
{
@@ -4850,310 +5032,70 @@ png_do_quantize(png_row_infop row_info, png_bytep row,
}
}
}
-#endif /* READ_QUANTIZE */
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
-/* Transform the row. The order of transformations is significant,
- * and is very touchy. If you add a transformation, take care to
- * decide how it fits in with the other transformations here.
- */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
void /* PRIVATE */
-png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
{
- png_debug(1, "in png_do_read_transformations");
+ png_debug(1, "in png_do_read_intrapixel");
- if (png_ptr->row_buf == NULL)
+ if (
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
{
- /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
- * error is incredibly rare and incredibly easy to debug without this
- * information.
- */
- png_error(png_ptr, "NULL row buffer");
- }
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
- /* The following is debugging; prior to 1.5.4 the code was never compiled in;
- * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
- * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for
- * all transformations, however in practice the ROW_INIT always gets done on
- * demand, if necessary.
- */
- if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
- (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
- {
- /* Application has failed to call either png_read_start_image() or
- * png_read_update_info() after setting transforms that expand pixels.
- * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
- */
- png_error(png_ptr, "Uninitialized row");
- }
-
-#ifdef PNG_READ_EXPAND_SUPPORTED
- if ((png_ptr->transformations & PNG_EXPAND) != 0)
- {
- if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ if (row_info->bit_depth == 8)
{
-#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE
- if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8))
- {
- if (png_ptr->riffled_palette == NULL)
- {
- /* Initialize the accelerated palette expansion. */
- png_ptr->riffled_palette =
- (png_bytep)png_malloc(png_ptr, 256 * 4);
- png_riffle_palette_neon(png_ptr);
- }
- }
-#endif
- png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1,
- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
- }
+ png_bytep rp;
+ png_uint_32 i;
- else
- {
- if (png_ptr->num_trans != 0 &&
- (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
- png_do_expand(row_info, png_ptr->row_buf + 1,
- &(png_ptr->trans_color));
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
else
- png_do_expand(row_info, png_ptr->row_buf + 1, NULL);
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
+ *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
+ }
}
- }
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
- (png_ptr->transformations & PNG_COMPOSE) == 0 &&
- (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
- row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
- png_do_strip_channel(row_info, png_ptr->row_buf + 1,
- 0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
- {
- int rgb_error =
- png_do_rgb_to_gray(png_ptr, row_info,
- png_ptr->row_buf + 1);
-
- if (rgb_error != 0)
+ else if (row_info->bit_depth == 16)
{
- png_ptr->rgb_to_gray_status=1;
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_WARN)
- png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ png_bytep rp;
+ png_uint_32 i;
- if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
- PNG_RGB_TO_GRAY_ERR)
- png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
+ png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp + 1) = (png_byte)(red & 0xff);
+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp + 5) = (png_byte)(blue & 0xff);
+ }
}
}
-#endif
-
-/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
- *
- * In most cases, the "simple transparency" should be done prior to doing
- * gray-to-RGB, or you will have to test 3x as many bytes to check if a
- * pixel is transparent. You would also need to make sure that the
- * transparency information is upgraded to RGB.
- *
- * To summarize, the current flow is:
- * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
- * with background "in place" if transparent,
- * convert to RGB if necessary
- * - Gray + alpha -> composite with gray background and remove alpha bytes,
- * convert to RGB if necessary
- *
- * To support RGB backgrounds for gray images we need:
- * - Gray + simple transparency -> convert to RGB + simple transparency,
- * compare 3 or 6 bytes and composite with
- * background "in place" if transparent
- * (3x compare/pixel compared to doing
- * composite with gray bkgrnd)
- * - Gray + alpha -> convert to RGB + alpha, composite with background and
- * remove alpha bytes (3x float
- * operations/pixel compared with composite
- * on gray background)
- *
- * Greg's change will do this. The reason it wasn't done before is for
- * performance, as this increases the per-pixel operations. If we would check
- * in advance if the background was gray or RGB, and position the gray-to-RGB
- * transform appropriately, then it would save a lot of work/time.
- */
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
- /* If gray -> RGB, do so now only if background is non-gray; else do later
- * for performance reasons
- */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
- png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
- defined(PNG_READ_ALPHA_MODE_SUPPORTED)
- if ((png_ptr->transformations & PNG_COMPOSE) != 0)
- png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
- if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- /* Because RGB_TO_GRAY does the gamma transform. */
- (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
-#endif
-#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
- defined(PNG_READ_ALPHA_MODE_SUPPORTED)
- /* Because PNG_COMPOSE does the gamma transform if there is something to
- * do (if there is an alpha channel or transparency.)
- */
- !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
- ((png_ptr->num_trans != 0) ||
- (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
-#endif
- /* Because png_init_read_transformations transforms the palette, unless
- * RGB_TO_GRAY will do the transform.
- */
- (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
- png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
- (png_ptr->transformations & PNG_COMPOSE) != 0 &&
- (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
- row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
- png_do_strip_channel(row_info, png_ptr->row_buf + 1,
- 0 /* at_start == false, because SWAP_ALPHA happens later */);
-#endif
-
-#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
- if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
- (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
- png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
-#endif
-
-#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
- if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
- png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
- /* There is no harm in doing both of these because only one has any effect,
- * by putting the 'scale' option first if the app asks for scale (either by
- * calling the API or in a TRANSFORM flag) this is what happens.
- */
- if ((png_ptr->transformations & PNG_16_TO_8) != 0)
- png_do_chop(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_QUANTIZE_SUPPORTED
- if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
- png_do_quantize(row_info, png_ptr->row_buf + 1,
- png_ptr->palette_lookup, png_ptr->quantize_index);
-#endif /* READ_QUANTIZE */
-
-#ifdef PNG_READ_EXPAND_16_SUPPORTED
- /* Do the expansion now, after all the arithmetic has been done. Notice
- * that previous transformations can handle the PNG_EXPAND_16 flag if this
- * is efficient (particularly true in the case of gamma correction, where
- * better accuracy results faster!)
- */
- if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
- png_do_expand_16(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
- /* NOTE: moved here in 1.5.4 (from much later in this list.) */
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
- (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
- png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_INVERT_SUPPORTED
- if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
- png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
- png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_SHIFT_SUPPORTED
- if ((png_ptr->transformations & PNG_SHIFT) != 0)
- png_do_unshift(row_info, png_ptr->row_buf + 1,
- &(png_ptr->shift));
-#endif
-
-#ifdef PNG_READ_PACK_SUPPORTED
- if ((png_ptr->transformations & PNG_PACK) != 0)
- png_do_unpack(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
- /* Added at libpng-1.5.10 */
- if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
- png_ptr->num_palette_max >= 0)
- png_do_check_palette_indexes(png_ptr, row_info);
-#endif
-
-#ifdef PNG_READ_BGR_SUPPORTED
- if ((png_ptr->transformations & PNG_BGR) != 0)
- png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
- png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_FILLER_SUPPORTED
- if ((png_ptr->transformations & PNG_FILLER) != 0)
- png_do_read_filler(row_info, png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->filler, png_ptr->flags);
-#endif
-
-#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
- png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_READ_16BIT_SUPPORTED
-#ifdef PNG_READ_SWAP_SUPPORTED
- if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
- png_do_swap(row_info, png_ptr->row_buf + 1);
-#endif
-#endif
-
-#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
- if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
- {
- if (png_ptr->read_user_transform_fn != NULL)
- (*(png_ptr->read_user_transform_fn)) /* User read transform function */
- (png_ptr, /* png_ptr */
- row_info, /* row_info: */
- /* png_uint_32 width; width of row */
- /* size_t rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
- if (png_ptr->user_transform_depth != 0)
- row_info->bit_depth = png_ptr->user_transform_depth;
-
- if (png_ptr->user_transform_channels != 0)
- row_info->channels = png_ptr->user_transform_channels;
-#endif
- row_info->pixel_depth = (png_byte)(row_info->bit_depth *
- row_info->channels);
-
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
- }
-#endif
}
-
-#endif /* READ_TRANSFORMS */
-#endif /* READ */
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngrutil.c b/Windows_Libs/Dev/Render/libpng/pngrutil.c
index a4eda54..01c3679 100644
--- a/Windows_Libs/Dev/Render/libpng/pngrutil.c
+++ b/Windows_Libs/Dev/Render/libpng/pngrutil.c
@@ -1,9 +1,10 @@
+
/* pngrutil.c - utilities to read a PNG file
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -17,25 +18,7 @@
#ifdef PNG_READ_SUPPORTED
-/* The minimum 'zlib' stream is assumed to be just the 2 byte header, 5 bytes
- * minimum 'deflate' stream, and the 4 byte checksum.
- */
-#define LZ77Min (2U+5U+4U)
-
-#ifdef PNG_READ_INTERLACING_SUPPORTED
-/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
-
-/* Start of interlace block */
-static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-/* Offset to next interlace block */
-static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-/* Start of interlace block in the y direction */
-static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-/* Offset to next interlace block in the y direction */
-static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-
-/* TODO: Move these arrays to a common utility module to avoid duplication. */
-#endif
+#define png_strtod(p,a,b) strtod(a,b)
png_uint_32 PNGAPI
png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
@@ -45,9 +28,33 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
if (uval > PNG_UINT_31_MAX)
png_error(png_ptr, "PNG unsigned integer out of range");
- return uval;
+ return (uval);
}
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
+/* The following is a variation on the above for use with the fixed
+ * point values used for gAMA and cHRM. Instead of png_error it
+ * issues a warning and returns (-1) - an invalid value because both
+ * gAMA and cHRM use *unsigned* integers for fixed point values.
+ */
+#define PNG_FIXED_ERROR (-1)
+
+static png_fixed_point /* PRIVATE */
+png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+
+ if (uval <= PNG_UINT_31_MAX)
+ return (png_fixed_point)uval; /* known to be in range */
+
+ /* The caller can turn off the warning by passing NULL. */
+ if (png_ptr != NULL)
+ png_warning(png_ptr, "PNG fixed point integer out of range");
+
+ return PNG_FIXED_ERROR;
+}
+#endif
+
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
/* NOTE: the read macros will obscure these definitions, so that if
* PNG_USE_READ_MACROS is set the library will not use them internally,
@@ -81,25 +88,19 @@ png_get_int_32)(png_const_bytep buf)
{
png_uint_32 uval = png_get_uint_32(buf);
if ((uval & 0x80000000) == 0) /* non-negative */
- return (png_int_32)uval;
+ return uval;
uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
- if ((uval & 0x80000000) == 0) /* no overflow */
- return -(png_int_32)uval;
- /* The following has to be safe; this function only gets called on PNG data
- * and if we get here that data is invalid. 0 is the most safe value and
- * if not then an attacker would surely just generate a PNG with 0 instead.
- */
- return 0;
+ return -(png_int_32)uval;
}
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
png_uint_16 (PNGAPI
png_get_uint_16)(png_const_bytep buf)
{
- /* ANSI-C requires an int value to accommodate at least 16 bits so this
+ /* ANSI-C requires an int value to accomodate at least 16 bits so this
* works and allows the compiler not to worry about possible narrowing
- * on 32-bit systems. (Pre-ANSI systems did not make integers smaller
+ * on 32 bit systems. (Pre-ANSI systems did not make integers smaller
* than 16 bits either.)
*/
unsigned int val =
@@ -109,13 +110,13 @@ png_get_uint_16)(png_const_bytep buf)
return (png_uint_16)val;
}
-#endif /* READ_INT_FUNCTIONS */
+#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
/* Read and check the PNG file signature */
void /* PRIVATE */
png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{
- size_t num_checked, num_to_check;
+ png_size_t num_checked, num_to_check;
/* Exit if the user application does not expect a signature. */
if (png_ptr->sig_bytes >= 8)
@@ -132,10 +133,10 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
png_ptr->sig_bytes = 8;
- if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
{
if (num_checked < 4 &&
- png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
png_error(png_ptr, "Not a PNG file");
else
png_error(png_ptr, "PNG file corrupted by ASCII conversion");
@@ -144,38 +145,6 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
}
-/* This function is called to verify that a chunk name is valid.
- * Do this using the bit-whacking approach from contrib/tools/pngfix.c
- *
- * Copied from libpng 1.7.
- */
-static int
-check_chunk_name(png_uint_32 name)
-{
- png_uint_32 t;
-
- /* Remove bit 5 from all but the reserved byte; this means
- * every 8-bit unit must be in the range 65-90 to be valid.
- * So bit 5 must be zero, bit 6 must be set and bit 7 zero.
- */
- name &= ~PNG_U32(32,32,0,32);
- t = (name & ~0x1f1f1f1fU) ^ 0x40404040U;
-
- /* Subtract 65 for each 8-bit quantity, this must not
- * overflow and each byte must then be in the range 0-25.
- */
- name -= PNG_U32(65,65,65,65);
- t |= name;
-
- /* Subtract 26, handling the overflow which should set the
- * top three bits of each byte.
- */
- name -= PNG_U32(25,25,25,26);
- t |= ~name;
-
- return (t & 0xe0e0e0e0U) == 0U;
-}
-
/* Read the chunk header (length + type name).
* Put the type name into png_ptr->chunk_name, and return the length.
*/
@@ -183,36 +152,30 @@ png_uint_32 /* PRIVATE */
png_read_chunk_header(png_structrp png_ptr)
{
png_byte buf[8];
- png_uint_32 chunk_name, length;
+ png_uint_32 length;
#ifdef PNG_IO_STATE_SUPPORTED
png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
#endif
- /* Read the length and the chunk name. png_struct::chunk_name is immediately
- * updated even if they are detectably wrong. This aids error message
- * handling by allowing png_chunk_error to be used.
+ /* Read the length and the chunk name.
+ * This must be performed in a single I/O call.
*/
png_read_data(png_ptr, buf, 8);
length = png_get_uint_31(png_ptr, buf);
- png_ptr->chunk_name = chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+
+ /* Put the chunk name into png_ptr->chunk_name. */
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+
+ png_debug2(0, "Reading %lx chunk, length = %lu",
+ (unsigned long)png_ptr->chunk_name, (unsigned long)length);
/* Reset the crc and run it over the chunk name. */
png_reset_crc(png_ptr);
png_calculate_crc(png_ptr, buf + 4, 4);
- png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu",
- (unsigned long)png_ptr->chunk_name, (unsigned long)length);
-
- /* Sanity check the length (first by <= 0x80) and the chunk name. An error
- * here indicates a broken stream and libpng has no recovery from this.
- */
- if (buf[0] >= 0x80U)
- png_chunk_error(png_ptr, "bad header (invalid length)");
-
/* Check to see if chunk name is valid. */
- if (!check_chunk_name(chunk_name))
- png_chunk_error(png_ptr, "bad header (invalid type)");
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
#ifdef PNG_IO_STATE_SUPPORTED
png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
@@ -232,85 +195,13 @@ png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
png_calculate_crc(png_ptr, buf, length);
}
-/* Compare the CRC stored in the PNG file with that calculated by libpng from
- * the data it has read thus far.
- */
-static int
-png_crc_error(png_structrp png_ptr, int handle_as_ancillary)
-{
- png_byte crc_bytes[4];
- png_uint_32 crc;
- int need_crc = 1;
-
- /* There are four flags two for ancillary and two for critical chunks. The
- * default setting of these flags is all zero.
- *
- * PNG_FLAG_CRC_ANCILLARY_USE
- * PNG_FLAG_CRC_ANCILLARY_NOWARN
- * USE+NOWARN: no CRC calculation (implemented here), else;
- * NOWARN: png_chunk_error on error (implemented in png_crc_finish)
- * else: png_chunk_warning on error (implemented in png_crc_finish)
- * This is the default.
- *
- * I.e. NOWARN without USE produces png_chunk_error. The default setting
- * where neither are set does the same thing.
- *
- * PNG_FLAG_CRC_CRITICAL_USE
- * PNG_FLAG_CRC_CRITICAL_IGNORE
- * IGNORE: no CRC calculation (implemented here), else;
- * USE: png_chunk_warning on error (implemented in png_crc_finish)
- * else: png_chunk_error on error (implemented in png_crc_finish)
- * This is the default.
- *
- * This arose because of original mis-implementation and has persisted for
- * compatibility reasons.
- *
- * TODO: the flag names are internal so maybe this can be changed to
- * something comprehensible.
- */
- if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
- (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
- need_crc = 0;
- }
-
- else /* critical */
- {
- if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
- need_crc = 0;
- }
-
-#ifdef PNG_IO_STATE_SUPPORTED
- png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
-#endif
-
- /* The chunk CRC must be serialized in a single I/O call. */
- png_read_data(png_ptr, crc_bytes, 4);
-
- if (need_crc != 0)
- {
- crc = png_get_uint_32(crc_bytes);
- return crc != png_ptr->crc;
- }
-
- else
- return 0;
-}
-
/* Optionally skip data and then check the CRC. Depending on whether we
* are reading an ancillary or critical chunk, and how the program has set
* things up, we may calculate the CRC on the data and print a message.
* Returns '1' if there was a CRC error, '0' otherwise.
- *
- * There is one public version which is used in most places and another which
- * takes the value for the 'critical' flag to check. This allows PLTE and IEND
- * handling code to ignore the CRC error and removes some confusing code
- * duplication.
*/
-static int
-png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip,
- int handle_as_ancillary)
+int /* PRIVATE */
+png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
{
/* The size of the local buffer for inflate is a good guess as to a
* reasonable size to use for buffering reads from the application.
@@ -328,59 +219,81 @@ png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip,
png_crc_read(png_ptr, tmpbuf, len);
}
- /* If 'handle_as_ancillary' has been requested and this is a critical chunk
- * but PNG_FLAG_CRC_CRITICAL_IGNORE was set then png_read_crc did not, in
- * fact, calculate the CRC so the ANCILLARY settings should not be used
- * instead.
- */
- if (handle_as_ancillary &&
- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
- handle_as_ancillary = 0;
-
- /* TODO: this might be more comprehensible if png_crc_error was inlined here.
- */
- if (png_crc_error(png_ptr, handle_as_ancillary) != 0)
+ if (png_crc_error(png_ptr))
{
- /* See above for the explanation of how the flags work. */
- if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
- (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :
- (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) ?
+ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
+ {
png_chunk_warning(png_ptr, "CRC error");
+ }
else
- png_chunk_error(png_ptr, "CRC error");
+ {
+ png_chunk_benign_error(png_ptr, "CRC error");
+ return (0);
+ }
- return 1;
+ return (1);
}
- return 0;
+ return (0);
}
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
int /* PRIVATE */
-png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
+png_crc_error(png_structrp png_ptr)
{
- return png_crc_finish_critical(png_ptr, skip, 0/*critical handling*/);
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
+ /* The chunk CRC must be serialized in a single I/O call. */
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+
+ else
+ return (0);
}
-#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
- defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
- defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
- defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_eXIf_SUPPORTED) ||\
- defined(PNG_SEQUENTIAL_READ_SUPPORTED)
/* Manage the read buffer; this simply reallocates the buffer if it is not small
* enough (or if it is not allocated). The routine returns a pointer to the
* buffer; if an error occurs and 'warn' is set the routine returns NULL, else
- * it will call png_error on failure.
+ * it will call png_error (via png_malloc) on failure. (warn == 2 means
+ * 'silent').
*/
static png_bytep
-png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size)
+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
{
png_bytep buffer = png_ptr->read_buffer;
- if (new_size > png_chunk_max(png_ptr)) return NULL;
-
if (buffer != NULL && new_size > png_ptr->read_buffer_size)
{
+ png_ptr->read_buffer = NULL;
png_ptr->read_buffer = NULL;
png_ptr->read_buffer_size = 0;
png_free(png_ptr, buffer);
@@ -393,17 +306,27 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size)
if (buffer != NULL)
{
-# ifndef PNG_NO_MEMZERO /* for detecting UIM bugs **only** */
- memset(buffer, 0, new_size); /* just in case */
-# endif
png_ptr->read_buffer = buffer;
png_ptr->read_buffer_size = new_size;
}
+
+ else if (warn < 2) /* else silent */
+ {
+#ifdef PNG_WARNINGS_SUPPORTED
+ if (warn)
+ png_chunk_warning(png_ptr, "insufficient memory to read chunk");
+ else
+#endif
+ {
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+ png_chunk_error(png_ptr, "insufficient memory to read chunk");
+#endif
+ }
+ }
}
return buffer;
}
-#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|eXIf|SEQUENTIAL_READ */
/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
* decompression. Returns Z_OK on success, else a zlib error code. It checks
@@ -411,7 +334,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size)
* chunk apparently owns the stream. Prior to release it does a png_error.
*/
static int
-png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner, int window_bits)
{
if (png_ptr->zowner != 0)
{
@@ -423,12 +346,12 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
* are minimal.
*/
(void)png_safecat(msg, (sizeof msg), 4, " using zstream");
-#if PNG_RELEASE_BUILD
- png_chunk_warning(png_ptr, msg);
- png_ptr->zowner = 0;
-#else
- png_chunk_error(png_ptr, msg);
-#endif
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+ png_chunk_warning(png_ptr, msg);
+ png_ptr->zowner = 0;
+# else
+ png_chunk_error(png_ptr, msg);
+# endif
}
/* Implementation note: unlike 'png_deflate_claim' this internal function
@@ -446,24 +369,6 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
*/
{
int ret; /* zlib return code */
-#if ZLIB_VERNUM >= 0x1240
- int window_bits = 0;
-
-# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
- if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
- PNG_OPTION_ON)
- {
- window_bits = 15;
- png_ptr->zstream_start = 0; /* fixed window size */
- }
-
- else
- {
- png_ptr->zstream_start = 1;
- }
-# endif
-
-#endif /* ZLIB_VERNUM >= 0x1240 */
/* Set this for safety, just in case the previous owner left pointers to
* memory allocations.
@@ -473,33 +378,28 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
png_ptr->zstream.next_out = NULL;
png_ptr->zstream.avail_out = 0;
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
{
-#if ZLIB_VERNUM >= 0x1240
- ret = inflateReset2(&png_ptr->zstream, window_bits);
-#else
- ret = inflateReset(&png_ptr->zstream);
-#endif
+# if ZLIB_VERNUM < 0x1240
+ PNG_UNUSED(window_bits)
+ ret = inflateReset(&png_ptr->zstream);
+# else
+ ret = inflateReset2(&png_ptr->zstream, window_bits);
+# endif
}
else
{
-#if ZLIB_VERNUM >= 0x1240
- ret = inflateInit2(&png_ptr->zstream, window_bits);
-#else
- ret = inflateInit(&png_ptr->zstream);
-#endif
+# if ZLIB_VERNUM < 0x1240
+ ret = inflateInit(&png_ptr->zstream);
+# else
+ ret = inflateInit2(&png_ptr->zstream, window_bits);
+# endif
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
-#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
- if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
- /* Turn off validation of the ADLER32 checksum in IDAT chunks */
- ret = inflateValidate(&png_ptr->zstream, 0);
-#endif
-
if (ret == Z_OK)
png_ptr->zowner = owner;
@@ -508,39 +408,9 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
return ret;
}
-
-#ifdef window_bits
-# undef window_bits
-#endif
}
-#if ZLIB_VERNUM >= 0x1240
-/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
- * in this case some zlib versions skip validation of the CINFO field and, in
- * certain circumstances, libpng may end up displaying an invalid image, in
- * contrast to implementations that call zlib in the normal way (e.g. libpng
- * 1.5).
- */
-int /* PRIVATE */
-png_zlib_inflate(png_structrp png_ptr, int flush)
-{
- if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
- {
- if ((*png_ptr->zstream.next_in >> 4) > 7)
- {
- png_ptr->zstream.msg = "invalid window size (libpng)";
- return Z_DATA_ERROR;
- }
-
- png_ptr->zstream_start = 0;
- }
-
- return inflate(&png_ptr->zstream, flush);
-}
-#endif /* Zlib >= 1.2.4 */
-
#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
-#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
* allow the caller to do multiple calls if required. If the 'finish' flag is
* set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
@@ -633,8 +503,8 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
* the previous chunk of input data. Tell zlib if we have reached the
* end of the output buffer.
*/
- ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :
- (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH :
+ (finish ? Z_FINISH : Z_SYNC_FLUSH));
} while (ret == Z_OK);
/* For safety kill the local buffer pointer now */
@@ -679,9 +549,9 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
*/
static int
png_decompress_chunk(png_structrp png_ptr,
- png_uint_32 chunklength, png_uint_32 prefix_size,
- png_alloc_size_t *newlength /* must be initialized to the maximum! */,
- int terminate /*add a '\0' to the end of the uncompressed data*/)
+ png_uint_32 chunklength, png_uint_32 prefix_size,
+ png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+ int terminate /*add a '\0' to the end of the uncompressed data*/)
{
/* TODO: implement different limits for different types of chunk.
*
@@ -690,7 +560,16 @@ png_decompress_chunk(png_structrp png_ptr,
* maybe a '\0' terminator too. We have to assume that 'prefix_size' is
* limited only by the maximum chunk size.
*/
- png_alloc_size_t limit = png_chunk_max(png_ptr);
+ png_alloc_size_t limit = PNG_SIZE_MAX;
+
+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
if (limit >= prefix_size + (terminate != 0))
{
@@ -701,16 +580,22 @@ png_decompress_chunk(png_structrp png_ptr,
if (limit < *newlength)
*newlength = limit;
- /* Now try to claim the stream. */
- ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
+ /* Now try to claim the stream; the 'warn' setting causes zlib to be told
+ * to use the maximum window size during inflate; this hides errors in the
+ * deflate header window bits value which is used if '0' is passed. In
+ * fact this only has an effect with zlib versions 1.2.4 and later - see
+ * the comments in png_inflate_claim above.
+ */
+ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name,
+ png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN ? 15 : 0);
if (ret == Z_OK)
{
png_uint_32 lzsize = chunklength - prefix_size;
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
- /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
- /* output: */ NULL, newlength);
+ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+ /* output: */ NULL, newlength);
if (ret == Z_STREAM_END)
{
@@ -730,23 +615,21 @@ png_decompress_chunk(png_structrp png_ptr,
*/
png_alloc_size_t new_size = *newlength;
png_alloc_size_t buffer_size = prefix_size + new_size +
- (terminate != 0);
+ (terminate != 0);
png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
- buffer_size));
+ buffer_size));
if (text != NULL)
{
- memset(text, 0, buffer_size);
-
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
- png_ptr->read_buffer + prefix_size, &lzsize,
- text + prefix_size, newlength);
+ png_ptr->read_buffer + prefix_size, &lzsize,
+ text + prefix_size, newlength);
if (ret == Z_STREAM_END)
{
if (new_size == *newlength)
{
- if (terminate != 0)
+ if (terminate)
text[prefix_size + *newlength] = 0;
if (prefix_size > 0)
@@ -785,7 +668,7 @@ png_decompress_chunk(png_structrp png_ptr,
* the extra space may otherwise be used as a Trojan Horse.
*/
if (ret == Z_STREAM_END &&
- chunklength - prefix_size != lzsize)
+ chunklength - prefix_size != lzsize)
png_chunk_benign_error(png_ptr, "extra compressed data");
}
@@ -801,7 +684,9 @@ png_decompress_chunk(png_structrp png_ptr,
{
/* inflateReset failed, store the error message */
png_zstream_error(png_ptr, ret);
- ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+ if (ret == Z_STREAM_END)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
}
}
@@ -825,8 +710,7 @@ png_decompress_chunk(png_structrp png_ptr,
return Z_MEM_ERROR;
}
}
-#endif /* READ_zTXt || READ_iTXt */
-#endif /* READ_COMPRESSED_TEXT */
+#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
#ifdef PNG_READ_iCCP_SUPPORTED
/* Perform a partial read and decompress, producing 'avail_out' bytes and
@@ -834,8 +718,8 @@ png_decompress_chunk(png_structrp png_ptr,
*/
static int
png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
- png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
- int finish)
+ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+ int finish)
{
if (png_ptr->zowner == png_ptr->chunk_name)
{
@@ -874,8 +758,8 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
* the available output is produced; this allows reading of truncated
* streams.
*/
- ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
- Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ ret = inflate(&png_ptr->zstream,
+ *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
}
while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
@@ -893,11 +777,10 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
return Z_STREAM_ERROR;
}
}
-#endif /* READ_iCCP */
+#endif
-/* CHUNK HANDLING */
/* Read and check the IDHR chunk */
-static png_handle_result_code
+void /* PRIVATE */
png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[13];
@@ -907,7 +790,12 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_IHDR");
- /* Length and position are checked by the caller. */
+ if (png_ptr->mode & PNG_HAVE_IHDR)
+ png_chunk_error(png_ptr, "out of place");
+
+ /* Check the length */
+ if (length != 13)
+ png_chunk_error(png_ptr, "invalid");
png_ptr->mode |= PNG_HAVE_IHDR;
@@ -956,244 +844,301 @@ png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
/* Set up other useful info */
- png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels);
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+ png_ptr->channels);
png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
png_debug1(3, "channels = %d", png_ptr->channels);
png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
-
- /* Rely on png_set_IHDR to completely validate the data and call png_error if
- * it's wrong.
- */
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
color_type, interlace_type, compression_type, filter_type);
-
- return handled_ok;
- PNG_UNUSED(length)
}
/* Read and check the palette */
-/* TODO: there are several obvious errors in this code when handling
- * out-of-place chunks and there is much over-complexity caused by trying to
- * patch up the problems.
- */
-static png_handle_result_code
+void /* PRIVATE */
png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- png_const_charp errmsg = NULL;
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ png_colorp pal_ptr;
+#endif
png_debug(1, "in png_handle_PLTE");
- /* 1.6.47: consistency. This used to be especially treated as a critical
- * error even in an image which is not colour mapped, there isn't a good
- * justification for treating some errors here one way and others another so
- * everything uses the same logic.
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ /* Moved to before the 'after IDAT' check below because otherwise duplicate
+ * PLTE chunks are potentially ignored (the spec says there shall not be more
+ * than one PLTE, the error is not treated as benign, so this check trumps
+ * the requirement that PLTE appears before IDAT.)
*/
- if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
- errmsg = "duplicate";
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ png_chunk_error(png_ptr, "duplicate");
- else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- errmsg = "out of place";
-
- else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
- errmsg = "ignored in grayscale PNG";
-
- else if (length > 3*PNG_MAX_PALETTE_LENGTH || (length % 3) != 0)
- errmsg = "invalid";
-
- /* This drops PLTE in favour of tRNS or bKGD because both of those chunks
- * can have an effect on the rendering of the image whereas PLTE only matters
- * in the case of an 8-bit display with a decoder which controls the palette.
- *
- * The alternative here is to ignore the error and store the palette anyway;
- * destroying the tRNS will definately cause problems.
- *
- * NOTE: the case of PNG_COLOR_TYPE_PALETTE need not be considered because
- * the png_handle_ routines for the three 'after PLTE' chunks tRNS, bKGD and
- * hIST all check for a preceding PLTE in these cases.
- */
- else if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE &&
- (png_has_chunk(png_ptr, tRNS) || png_has_chunk(png_ptr, bKGD)))
- errmsg = "out of place";
-
- else
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
{
- /* If the palette has 256 or fewer entries but is too large for the bit
- * depth we don't issue an error to preserve the behavior of previous
- * libpng versions. We silently truncate the unused extra palette entries
- * here.
+ /* This is benign because the non-benign error happened before, when an
+ * IDAT was encountered in a color-mapped image with no PLTE.
*/
- const unsigned max_palette_length =
- (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
- 1U << png_ptr->bit_depth : PNG_MAX_PALETTE_LENGTH;
-
- /* The cast is safe because 'length' is less than
- * 3*PNG_MAX_PALETTE_LENGTH
- */
- const unsigned num = (length > 3U*max_palette_length) ?
- max_palette_length : (unsigned)length / 3U;
-
- unsigned i, j;
- png_byte buf[3*PNG_MAX_PALETTE_LENGTH];
- png_color palette[PNG_MAX_PALETTE_LENGTH];
-
- /* Read the chunk into the buffer then read to the end of the chunk. */
- png_crc_read(png_ptr, buf, num*3U);
- png_crc_finish_critical(png_ptr, length - 3U*num,
- /* Handle as ancillary if PLTE is optional: */
- png_ptr->color_type != PNG_COLOR_TYPE_PALETTE);
-
- for (i = 0U, j = 0U; i < num; i++)
- {
- palette[i].red = buf[j++];
- palette[i].green = buf[j++];
- palette[i].blue = buf[j++];
- }
-
- /* A valid PLTE chunk has been read */
- png_ptr->mode |= PNG_HAVE_PLTE;
-
- /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to
- * its own copy of the palette. This has the side effect that when
- * png_start_row is called (this happens after any call to
- * png_read_update_info) the info_ptr palette gets changed. This is
- * extremely unexpected and confusing.
- *
- * REVIEW: there have been consistent bugs in the past about gamma and
- * similar transforms to colour mapped images being useless because the
- * modified palette cannot be accessed because of the above.
- *
- * CONSIDER: Fix this by not sharing the palette in this way. But does
- * this completely fix the problem?
- */
- png_set_PLTE(png_ptr, info_ptr, palette, num);
- return handled_ok;
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
}
- /* Here on error: errmsg is non NULL. */
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
{
png_crc_finish(png_ptr, length);
- png_chunk_error(png_ptr, errmsg);
+ png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
+ return;
}
- else /* not critical to this image */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
{
- png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
- png_chunk_benign_error(png_ptr, errmsg);
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ png_crc_finish(png_ptr, length);
+
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ png_chunk_benign_error(png_ptr, "invalid");
+
+ else
+ png_chunk_error(png_ptr, "invalid");
+
+ return;
}
- /* Because PNG_UNUSED(errmsg) does not work if all the uses are compiled out
- * (this does happen).
+ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
+ num = (int)length / 3;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* Don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually need the PLTE chunk (ie for a paletted image), we do
+ * whatever the normal CRC configuration tells us. However, if we
+ * have an RGB image, the PLTE can be considered ancillary, so
+ * we will act as though it is.
*/
- return errmsg != NULL ? handled_error : handled_error;
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, 0);
+ }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ * we have two options: an error abort, or a warning and we
+ * ignore the data in this chunk (which should be OK, since
+ * it's considered ancillary for a RGB or RGBA image).
+ *
+ * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
+ * chunk type to determine whether to check the ancillary or the critical
+ * flags.
+ */
+ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+ {
+ png_chunk_benign_error(png_ptr, "CRC error");
+ }
+
+ else
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ return;
+ }
+ }
+
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ }
+#endif
+
+ /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
+ * own copy of the palette. This has the side effect that when png_start_row
+ * is called (this happens after any call to png_read_update_info) the
+ * info_ptr palette gets changed. This is extremely unexpected and
+ * confusing.
+ *
+ * Fix this by not sharing the palette in this way.
+ */
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
+ * IDAT. Prior to 1.6.0 this was not checked; instead the code merely
+ * checked the apparent validity of a tRNS chunk inserted before PLTE on a
+ * palette PNG. 1.6.0 attempts to rigorously follow the standard and
+ * therefore does a benign error if the erroneous condition is detected *and*
+ * cancels the tRNS if the benign error returns. The alternative is to
+ * amend the standard since it would be rather hypocritical of the standards
+ * maintainers to ignore it.
+ */
+#ifdef PNG_READ_tRNS_SUPPORTED
+ if (png_ptr->num_trans > 0 ||
+ (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
+ {
+ /* Cancel this because otherwise it would be used if the transforms
+ * require it. Don't cancel the 'valid' flag because this would prevent
+ * detection of duplicate chunks.
+ */
+ png_ptr->num_trans = 0;
+
+ if (info_ptr != NULL)
+ info_ptr->num_trans = 0;
+
+ png_chunk_benign_error(png_ptr, "tRNS must be after");
+ }
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+ png_chunk_benign_error(png_ptr, "hIST must be after");
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+ png_chunk_benign_error(png_ptr, "bKGD must be after");
+#endif
}
-/* On read the IDAT chunk is always handled specially, even if marked for
- * unknown handling (this is allowed), so:
- */
-#define png_handle_IDAT NULL
-
-static png_handle_result_code
+void /* PRIVATE */
png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_debug(1, "in png_handle_IEND");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+ png_chunk_error(png_ptr, "out of place");
+
png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+ png_crc_finish(png_ptr, length);
+
if (length != 0)
png_chunk_benign_error(png_ptr, "invalid");
- png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
-
- return handled_ok;
PNG_UNUSED(info_ptr)
}
#ifdef PNG_READ_gAMA_SUPPORTED
-static png_handle_result_code
+void /* PRIVATE */
png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- png_uint_32 ugamma;
+ png_fixed_point igamma;
png_byte buf[4];
png_debug(1, "in png_handle_gAMA");
- png_crc_read(png_ptr, buf, 4);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- ugamma = png_get_uint_32(buf);
-
- if (ugamma > PNG_UINT_31_MAX)
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
{
- png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
}
- png_set_gAMA_fixed(png_ptr, info_ptr, (png_fixed_point)/*SAFE*/ugamma);
+ if (length != 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
-#ifdef PNG_READ_GAMMA_SUPPORTED
- /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. gAMA is
- * at the end of the chain so simply check for an unset value.
- */
- if (png_ptr->chunk_gamma == 0)
- png_ptr->chunk_gamma = (png_fixed_point)/*SAFE*/ugamma;
-#endif /*READ_GAMMA*/
+ png_crc_read(png_ptr, buf, 4);
- return handled_ok;
- PNG_UNUSED(length)
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ igamma = png_get_fixed_point(NULL, buf);
+
+ png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
+ png_colorspace_sync(png_ptr, info_ptr);
}
-#else
-# define png_handle_gAMA NULL
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- unsigned int truelen, i;
- png_byte sample_depth;
+ unsigned int truelen;
png_byte buf[4];
png_debug(1, "in png_handle_sBIT");
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- truelen = 3;
- sample_depth = 8;
- }
+ buf[0] = buf[1] = buf[2] = buf[3] = 0;
- else
- {
- truelen = png_ptr->channels;
- sample_depth = png_ptr->bit_depth;
- }
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- if (length != truelen)
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
{
png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, "bad length");
- return handled_error;
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 3;
+
+ else
+ truelen = png_ptr->channels;
+
+ if (length != truelen || length > 4)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ png_crc_finish(png_ptr, length);
+ return;
}
- buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
- for (i=0; i sample_depth)
- {
- png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
- }
- }
-
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
{
png_ptr->sig_bit.red = buf[0];
png_ptr->sig_bit.green = buf[1];
@@ -1201,7 +1146,7 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_ptr->sig_bit.alpha = buf[3];
}
- else /* grayscale */
+ else
{
png_ptr->sig_bit.gray = buf[0];
png_ptr->sig_bit.red = buf[0];
@@ -1211,132 +1156,133 @@ png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
- return handled_ok;
}
-#else
-# define png_handle_sBIT NULL
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
-static png_int_32
-png_get_int_32_checked(png_const_bytep buf, int *error)
-{
- png_uint_32 uval = png_get_uint_32(buf);
- if ((uval & 0x80000000) == 0) /* non-negative */
- return (png_int_32)uval;
-
- uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
- if ((uval & 0x80000000) == 0) /* no overflow */
- return -(png_int_32)uval;
-
- /* This version of png_get_int_32 has a way of returning the error to the
- * caller, so:
- */
- *error = 1;
- return 0; /* Safe */
-}
-
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- int error = 0;
- png_xy xy;
png_byte buf[32];
+ png_xy xy;
png_debug(1, "in png_handle_cHRM");
- png_crc_read(png_ptr, buf, 32);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- xy.whitex = png_get_int_32_checked(buf + 0, &error);
- xy.whitey = png_get_int_32_checked(buf + 4, &error);
- xy.redx = png_get_int_32_checked(buf + 8, &error);
- xy.redy = png_get_int_32_checked(buf + 12, &error);
- xy.greenx = png_get_int_32_checked(buf + 16, &error);
- xy.greeny = png_get_int_32_checked(buf + 20, &error);
- xy.bluex = png_get_int_32_checked(buf + 24, &error);
- xy.bluey = png_get_int_32_checked(buf + 28, &error);
-
- if (error)
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
{
- png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
}
- /* png_set_cHRM may complain about some of the values but this doesn't matter
- * because it was a cHRM and it did have vaguely (if, perhaps, ridiculous)
- * values. Ridiculousity will be checked if the values are used later.
- */
- png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
- xy.greenx, xy.greeny, xy.bluex, xy.bluey);
+ if (length != 32)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
- /* We only use 'chromaticities' for RGB to gray */
-# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- /* There is no need to check sRGB here, cICP is NYI and iCCP is not
- * supported so just check mDCV.
- */
- if (!png_has_chunk(png_ptr, mDCV))
- {
- png_ptr->chromaticities = xy;
- }
-# endif /* READ_RGB_TO_GRAY */
+ png_crc_read(png_ptr, buf, 32);
- return handled_ok;
- PNG_UNUSED(length)
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ xy.whitex = png_get_fixed_point(NULL, buf);
+ xy.whitey = png_get_fixed_point(NULL, buf + 4);
+ xy.redx = png_get_fixed_point(NULL, buf + 8);
+ xy.redy = png_get_fixed_point(NULL, buf + 12);
+ xy.greenx = png_get_fixed_point(NULL, buf + 16);
+ xy.greeny = png_get_fixed_point(NULL, buf + 20);
+ xy.bluex = png_get_fixed_point(NULL, buf + 24);
+ xy.bluey = png_get_fixed_point(NULL, buf + 28);
+
+ if (xy.whitex == PNG_FIXED_ERROR ||
+ xy.whitey == PNG_FIXED_ERROR ||
+ xy.redx == PNG_FIXED_ERROR ||
+ xy.redy == PNG_FIXED_ERROR ||
+ xy.greenx == PNG_FIXED_ERROR ||
+ xy.greeny == PNG_FIXED_ERROR ||
+ xy.bluex == PNG_FIXED_ERROR ||
+ xy.bluey == PNG_FIXED_ERROR)
+ {
+ png_chunk_benign_error(png_ptr, "invalid values");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+ (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
+ 1/*prefer cHRM values*/);
+ png_colorspace_sync(png_ptr, info_ptr);
}
-#else
-# define png_handle_cHRM NULL
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte intent;
png_debug(1, "in png_handle_sRGB");
- png_crc_read(png_ptr, &intent, 1);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- /* This checks the range of the "rendering intent" because it is specified in
- * the PNG spec itself; the "reserved" values will result in the chunk not
- * being accepted, just as they do with the various "reserved" values in
- * IHDR.
- */
- if (intent > 3/*PNGv3 spec*/)
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
{
- png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
}
- png_set_sRGB(png_ptr, info_ptr, intent);
- /* NOTE: png_struct::chromaticities is not set here because the RGB to gray
- * coefficients are known without a need for the chromaticities.
+ if (length != 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, &intent, 1);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
*/
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "too many profiles");
+ return;
+ }
-#ifdef PNG_READ_GAMMA_SUPPORTED
- /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. iCCP is
- * not supported by libpng so the only requirement is to check for cICP
- * setting the gamma (this is NYI, but this check is safe.)
- */
- if (!png_has_chunk(png_ptr, cICP) || png_ptr->chunk_gamma == 0)
- png_ptr->chunk_gamma = PNG_GAMMA_sRGB_INVERSE;
-#endif /*READ_GAMMA*/
-
- return handled_ok;
- PNG_UNUSED(length)
+ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
+ png_colorspace_sync(png_ptr, info_ptr);
}
-#else
-# define png_handle_sRGB NULL
-#endif /* READ_sRGB */
+#endif /* PNG_READ_sRGB_SUPPORTED */
#ifdef PNG_READ_iCCP_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* Note: this does not properly handle profiles that are > 64K under DOS */
{
@@ -1345,10 +1291,42 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_iCCP");
- /* PNGv3: allow PNG files with both sRGB and iCCP because the PNG spec only
- * ever said that there "should" be only one, not "shall" and the PNGv3
- * colour chunk precedence rules give a handling for this case anyway.
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ /* Consistent with all the above colorspace handling an obviously *invalid*
+ * chunk is just ignored, so does not invalidate the color space. An
+ * alternative is to set the 'invalid' flags at the start of this routine
+ * and only clear them in they were not set before and all the tests pass.
+ * The minimum 'deflate' stream is assumed to be just the 2 byte header and 4
+ * byte checksum. The keyword must be one character and there is a
+ * terminator (0) byte and the compression method.
*/
+ if (length < 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
{
uInt read_length, keyword_length;
char keyword[81];
@@ -1358,18 +1336,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
*/
read_length = 81; /* maximum */
if (read_length > length)
- read_length = (uInt)/*SAFE*/length;
+ read_length = (uInt)length;
png_crc_read(png_ptr, (png_bytep)keyword, read_length);
length -= read_length;
- if (length < LZ77Min)
- {
- png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, "too short");
- return handled_error;
- }
-
keyword_length = 0;
while (keyword_length < 80 && keyword_length < read_length &&
keyword[keyword_length] != 0)
@@ -1386,75 +1357,79 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
read_length -= keyword_length+2;
- if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
+ if (png_inflate_claim(png_ptr, png_iCCP,
+ png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN ? 15 : 0) == Z_OK)
{
- Byte profile_header[132]={0};
+ Byte profile_header[132];
Byte local_buffer[PNG_INFLATE_BUF_SIZE];
png_alloc_size_t size = (sizeof profile_header);
png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
png_ptr->zstream.avail_in = read_length;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length, profile_header, &size,
- 0/*finish: don't, because the output is too small*/);
+ (sizeof local_buffer), &length, profile_header, &size,
+ 0/*finish: don't, because the output is too small*/);
if (size == 0)
{
/* We have the ICC profile header; do the basic header checks.
*/
- png_uint_32 profile_length = png_get_uint_32(profile_header);
+ const png_uint_32 profile_length =
+ png_get_uint_32(profile_header);
- if (png_icc_check_length(png_ptr, keyword, profile_length) !=
- 0)
+ if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length))
{
/* The length is apparently ok, so we can check the 132
* byte header.
*/
- if (png_icc_check_header(png_ptr, keyword, profile_length,
- profile_header, png_ptr->color_type) != 0)
+ if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length, profile_header,
+ png_ptr->color_type))
{
/* Now read the tag table; a variable size buffer is
* needed at this point, allocate one for the whole
* profile. The header check has already validated
- * that none of this stuff will overflow.
+ * that none of these stuff will overflow.
*/
- png_uint_32 tag_count =
- png_get_uint_32(profile_header + 128);
+ const png_uint_32 tag_count = png_get_uint_32(
+ profile_header+128);
png_bytep profile = png_read_buffer(png_ptr,
- profile_length);
+ profile_length, 2/*silent*/);
if (profile != NULL)
{
memcpy(profile, profile_header,
- (sizeof profile_header));
+ (sizeof profile_header));
size = 12 * tag_count;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length,
- profile + (sizeof profile_header), &size, 0);
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header), &size, 0);
- /* Still expect a buffer error because we expect
+ /* Still expect a a buffer error because we expect
* there to be some tag data!
*/
if (size == 0)
{
if (png_icc_check_tag_table(png_ptr,
- keyword, profile_length, profile) != 0)
+ &png_ptr->colorspace, keyword, profile_length,
+ profile))
{
/* The profile has been validated for basic
* security issues, so read the whole thing in.
*/
size = profile_length - (sizeof profile_header)
- - 12 * tag_count;
+ - 12 * tag_count;
(void)png_inflate_read(png_ptr, local_buffer,
- (sizeof local_buffer), &length,
- profile + (sizeof profile_header) +
- 12 * tag_count, &size, 1/*finish*/);
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header) +
+ 12 * tag_count, &size, 1/*finish*/);
if (length > 0 && !(png_ptr->flags &
- PNG_FLAG_BENIGN_ERRORS_WARN))
+ PNG_FLAG_BENIGN_ERRORS_WARN))
errmsg = "extra compressed data";
/* But otherwise allow extra data: */
@@ -1466,27 +1441,34 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
* keep going.
*/
png_chunk_warning(png_ptr,
- "extra compressed data");
+ "extra compressed data");
}
png_crc_finish(png_ptr, length);
finished = 1;
+# ifdef PNG_sRGB_SUPPORTED
+ /* Check for a match against sRGB */
+ png_icc_set_sRGB(png_ptr,
+ &png_ptr->colorspace, profile,
+ png_ptr->zstream.adler);
+# endif
+
/* Steal the profile for info_ptr. */
if (info_ptr != NULL)
{
png_free_data(png_ptr, info_ptr,
- PNG_FREE_ICCP, 0);
+ PNG_FREE_ICCP, 0);
info_ptr->iccp_name = png_voidcast(char*,
- png_malloc_base(png_ptr,
- keyword_length+1));
+ png_malloc_base(png_ptr,
+ keyword_length+1));
if (info_ptr->iccp_name != NULL)
{
memcpy(info_ptr->iccp_name, keyword,
- keyword_length+1);
+ keyword_length+1);
info_ptr->iccp_proflen =
- profile_length;
+ profile_length;
info_ptr->iccp_profile = profile;
png_ptr->read_buffer = NULL; /*steal*/
info_ptr->free_me |= PNG_FREE_ICCP;
@@ -1494,7 +1476,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
else
+ {
+ png_ptr->colorspace.flags |=
+ PNG_COLORSPACE_INVALID;
errmsg = "out of memory";
+ }
}
/* else the profile remains in the read
@@ -1502,17 +1488,26 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
* chunks.
*/
+ if (info_ptr != NULL)
+ png_colorspace_sync(png_ptr, info_ptr);
+
if (errmsg == NULL)
{
png_ptr->zowner = 0;
- return handled_ok;
+ return;
}
}
- if (errmsg == NULL)
+
+ else if (size > 0)
+ errmsg = "truncated";
+
+ else
errmsg = png_ptr->zstream.msg;
}
+
/* else png_icc_check_tag_table output an error */
}
+
else /* profile truncated */
errmsg = png_ptr->zstream.msg;
}
@@ -1546,21 +1541,22 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
errmsg = "bad keyword";
}
+ else
+ errmsg = "too many profiles";
+
/* Failure: the reason is in 'errmsg' */
- if (finished == 0)
+ if (!finished)
png_crc_finish(png_ptr, length);
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
if (errmsg != NULL) /* else already output */
png_chunk_benign_error(png_ptr, errmsg);
-
- return handled_error;
}
-#else
-# define png_handle_iCCP NULL
-#endif /* READ_iCCP */
+#endif /* PNG_READ_iCCP_SUPPORTED */
#ifdef PNG_READ_sPLT_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
@@ -1571,7 +1567,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
int entry_size, i;
png_uint_32 skip = 0;
png_uint_32 dl;
- size_t max_dl;
+ png_size_t max_dl;
png_debug(1, "in png_handle_sPLT");
@@ -1581,24 +1577,43 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
- return handled_error;
+ return;
}
if (--png_ptr->user_chunk_cache_max == 1)
{
png_warning(png_ptr, "No space in chunk cache for sPLT");
png_crc_finish(png_ptr, length);
- return handled_error;
+ return;
}
}
#endif
- buffer = png_read_buffer(png_ptr, length+1);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
if (buffer == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ return;
}
@@ -1608,8 +1623,8 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
*/
png_crc_read(png_ptr, buffer, length);
- if (png_crc_finish(png_ptr, skip) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, skip))
+ return;
buffer[length] = 0;
@@ -1619,10 +1634,10 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
++entry_start;
/* A sample depth should follow the separator, and we should be on it */
- if (length < 2U || entry_start > buffer + (length - 2U))
+ if (entry_start > buffer + length - 2)
{
png_warning(png_ptr, "malformed sPLT chunk");
- return handled_error;
+ return;
}
new_palette.depth = *entry_start++;
@@ -1633,32 +1648,33 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
data_length = length - (png_uint_32)(entry_start - buffer);
/* Integrity-check the data length */
- if ((data_length % (unsigned int)entry_size) != 0)
+ if (data_length % entry_size)
{
png_warning(png_ptr, "sPLT chunk has bad length");
- return handled_error;
+ return;
}
- dl = (png_uint_32)(data_length / (unsigned int)entry_size);
+ dl = (png_int_32)(data_length / entry_size);
max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
if (dl > max_dl)
{
- png_warning(png_ptr, "sPLT chunk too long");
- return handled_error;
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
}
- new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
+ new_palette.nentries = (png_int_32)(data_length / entry_size);
- new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
- (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+ png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
if (new_palette.entries == NULL)
{
- png_warning(png_ptr, "sPLT chunk requires too much memory");
- return handled_error;
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
}
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
for (i = 0; i < new_palette.nentries; i++)
{
pp = new_palette.entries + i;
@@ -1681,6 +1697,31 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
}
+#else
+ pp = new_palette.entries;
+
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+
+ pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
/* Discard all chunk data except the name and stash that */
new_palette.name = (png_charp)buffer;
@@ -1688,20 +1729,34 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
png_free(png_ptr, new_palette.entries);
- return handled_ok;
}
-#else
-# define png_handle_sPLT NULL
-#endif /* READ_sPLT */
+#endif /* PNG_READ_sPLT_SUPPORTED */
#ifdef PNG_READ_tRNS_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
png_debug(1, "in png_handle_tRNS");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{
png_byte buf[2];
@@ -1710,7 +1765,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buf, 2);
@@ -1726,7 +1781,7 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buf, length);
@@ -1738,20 +1793,20 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
- if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_PLTE))
{
+ /* TODO: is this actually an error in the ISO spec? */
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of place");
- return handled_error;
+ return;
}
- if (length > (unsigned int) png_ptr->num_palette ||
- length > (unsigned int) PNG_MAX_PALETTE_LENGTH ||
+ if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH ||
length == 0)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, readbuf, length);
@@ -1762,13 +1817,13 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid with alpha channel");
- return handled_error;
+ return;
}
- if (png_crc_finish(png_ptr, 0) != 0)
+ if (png_crc_finish(png_ptr, 0))
{
png_ptr->num_trans = 0;
- return handled_error;
+ return;
}
/* TODO: this is a horrible side effect in the palette case because the
@@ -1777,14 +1832,11 @@ png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
*/
png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
&(png_ptr->trans_color));
- return handled_ok;
}
-#else
-# define png_handle_tRNS NULL
#endif
#ifdef PNG_READ_bKGD_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
unsigned int truelen;
@@ -1793,19 +1845,29 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_bKGD");
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
- {
- if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
- {
- png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, "out of place");
- return handled_error;
- }
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- truelen = 1;
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE)))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
}
- else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+
+ else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
truelen = 6;
else
@@ -1815,13 +1877,13 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buf, truelen);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
/* We convert the index value into RGB components so that we can allow
* arbitrary RGB values for background when we have transparency, and
@@ -1832,12 +1894,12 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
background.index = buf[0];
- if (info_ptr != NULL && info_ptr->num_palette != 0)
+ if (info_ptr && info_ptr->num_palette)
{
if (buf[0] >= info_ptr->num_palette)
{
png_chunk_benign_error(png_ptr, "invalid index");
- return handled_error;
+ return;
}
background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
@@ -1851,17 +1913,8 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
background.gray = 0;
}
- else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
+ else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
{
- if (png_ptr->bit_depth <= 8)
- {
- if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
- {
- png_chunk_benign_error(png_ptr, "invalid gray level");
- return handled_error;
- }
- }
-
background.index = 0;
background.red =
background.green =
@@ -1871,15 +1924,6 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
else
{
- if (png_ptr->bit_depth <= 8)
- {
- if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
- {
- png_chunk_benign_error(png_ptr, "invalid color");
- return handled_error;
- }
- }
-
background.index = 0;
background.red = png_get_uint_16(buf);
background.green = png_get_uint_16(buf + 2);
@@ -1888,174 +1932,11 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
png_set_bKGD(png_ptr, info_ptr, &background);
- return handled_ok;
}
-#else
-# define png_handle_bKGD NULL
-#endif
-
-#ifdef PNG_READ_cICP_SUPPORTED
-static png_handle_result_code /* PRIVATE */
-png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
-{
- png_byte buf[4];
-
- png_debug(1, "in png_handle_cICP");
-
- png_crc_read(png_ptr, buf, 4);
-
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- png_set_cICP(png_ptr, info_ptr, buf[0], buf[1], buf[2], buf[3]);
-
- /* We only use 'chromaticities' for RGB to gray */
-# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- if (!png_has_chunk(png_ptr, mDCV))
- {
- /* TODO: png_ptr->chromaticities = chromaticities; */
- }
-# endif /* READ_RGB_TO_GRAY */
-
-#ifdef PNG_READ_GAMMA_SUPPORTED
- /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA. cICP is
- * at the head so simply set the gamma if it can be determined. If not
- * chunk_gamma remains unchanged; sRGB and gAMA handling check it for
- * being zero.
- */
- /* TODO: set png_struct::chunk_gamma when possible */
-#endif /*READ_GAMMA*/
-
- return handled_ok;
- PNG_UNUSED(length)
-}
-#else
-# define png_handle_cICP NULL
-#endif
-
-#ifdef PNG_READ_cLLI_SUPPORTED
-static png_handle_result_code /* PRIVATE */
-png_handle_cLLI(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
-{
- png_byte buf[8];
-
- png_debug(1, "in png_handle_cLLI");
-
- png_crc_read(png_ptr, buf, 8);
-
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- /* The error checking happens here, this puts it in just one place: */
- png_set_cLLI_fixed(png_ptr, info_ptr, png_get_uint_32(buf),
- png_get_uint_32(buf+4));
- return handled_ok;
- PNG_UNUSED(length)
-}
-#else
-# define png_handle_cLLI NULL
-#endif
-
-#ifdef PNG_READ_mDCV_SUPPORTED
-static png_handle_result_code /* PRIVATE */
-png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
-{
- png_xy chromaticities;
- png_byte buf[24];
-
- png_debug(1, "in png_handle_mDCV");
-
- png_crc_read(png_ptr, buf, 24);
-
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- /* The error checking happens here, this puts it in just one place. The
- * odd /50000 scaling factor makes it more difficult but the (x.y) values are
- * only two bytes so a <<1 is safe.
- *
- * WARNING: the PNG specification defines the cHRM chunk to **start** with
- * the white point (x,y). The W3C PNG v3 specification puts the white point
- * **after* R,G,B. The x,y values in mDCV are also scaled by 50,000 and
- * stored in just two bytes, whereas those in cHRM are scaled by 100,000 and
- * stored in four bytes. This is very, very confusing. These APIs remove
- * the confusion by copying the existing, well established, API.
- */
- chromaticities.redx = png_get_uint_16(buf+ 0U) << 1; /* red x */
- chromaticities.redy = png_get_uint_16(buf+ 2U) << 1; /* red y */
- chromaticities.greenx = png_get_uint_16(buf+ 4U) << 1; /* green x */
- chromaticities.greeny = png_get_uint_16(buf+ 6U) << 1; /* green y */
- chromaticities.bluex = png_get_uint_16(buf+ 8U) << 1; /* blue x */
- chromaticities.bluey = png_get_uint_16(buf+10U) << 1; /* blue y */
- chromaticities.whitex = png_get_uint_16(buf+12U) << 1; /* white x */
- chromaticities.whitey = png_get_uint_16(buf+14U) << 1; /* white y */
-
- png_set_mDCV_fixed(png_ptr, info_ptr,
- chromaticities.whitex, chromaticities.whitey,
- chromaticities.redx, chromaticities.redy,
- chromaticities.greenx, chromaticities.greeny,
- chromaticities.bluex, chromaticities.bluey,
- png_get_uint_32(buf+16U), /* peak luminance */
- png_get_uint_32(buf+20U));/* minimum perceivable luminance */
-
- /* We only use 'chromaticities' for RGB to gray */
-# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- png_ptr->chromaticities = chromaticities;
-# endif /* READ_RGB_TO_GRAY */
-
- return handled_ok;
- PNG_UNUSED(length)
-}
-#else
-# define png_handle_mDCV NULL
-#endif
-
-#ifdef PNG_READ_eXIf_SUPPORTED
-static png_handle_result_code /* PRIVATE */
-png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
-{
- png_bytep buffer = NULL;
-
- png_debug(1, "in png_handle_eXIf");
-
- buffer = png_read_buffer(png_ptr, length);
-
- if (buffer == NULL)
- {
- png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
- }
-
- png_crc_read(png_ptr, buffer, length);
-
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
-
- /* PNGv3: the code used to check the byte order mark at the start for MM or
- * II, however PNGv3 states that the the first 4 bytes should be checked.
- * The caller ensures that there are four bytes available.
- */
- {
- png_uint_32 header = png_get_uint_32(buffer);
-
- /* These numbers are copied from the PNGv3 spec: */
- if (header != 0x49492A00 && header != 0x4D4D002A)
- {
- png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
- }
- }
-
- png_set_eXIf_1(png_ptr, info_ptr, length, buffer);
- return handled_ok;
-}
-#else
-# define png_handle_eXIf NULL
#endif
#ifdef PNG_READ_hIST_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
unsigned int num, i;
@@ -2063,21 +1944,30 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_hIST");
- /* This cast is safe because the chunk definition limits the length to a
- * maximum of 1024 bytes.
- *
- * TODO: maybe use png_uint_32 anyway, not unsigned int, to reduce the
- * casts.
- */
- num = (unsigned int)length / 2 ;
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
- if (length != num * 2 ||
- num != (unsigned int)png_ptr->num_palette ||
- num > (unsigned int)PNG_MAX_PALETTE_LENGTH)
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) || !(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ num = length / 2 ;
+
+ if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
for (i = 0; i < num; i++)
@@ -2088,18 +1978,15 @@ png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
readbuf[i] = png_get_uint_16(buf);
}
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
png_set_hIST(png_ptr, info_ptr, readbuf);
- return handled_ok;
}
-#else
-# define png_handle_hIST NULL
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[9];
@@ -2108,24 +1995,44 @@ png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_pHYs");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
res_x = png_get_uint_32(buf);
res_y = png_get_uint_32(buf + 4);
unit_type = buf[8];
png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
- return handled_ok;
- PNG_UNUSED(length)
}
-#else
-# define png_handle_pHYs NULL
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[9];
@@ -2134,25 +2041,45 @@ png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_oFFs");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
png_crc_read(png_ptr, buf, 9);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
offset_x = png_get_int_32(buf);
offset_y = png_get_int_32(buf + 4);
unit_type = buf[8];
png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
- return handled_ok;
- PNG_UNUSED(length)
}
-#else
-# define png_handle_oFFs NULL
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
/* Read the pCAL chunk (described in the PNG Extensions document) */
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_int_32 X0, X1;
@@ -2162,22 +2089,40 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
int i;
png_debug(1, "in png_handle_pCAL");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
length + 1);
- buffer = png_read_buffer(png_ptr, length+1);
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
if (buffer == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buffer, length);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
buffer[length] = 0; /* Null terminate the last string */
@@ -2190,10 +2135,10 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* We need to have at least 12 bytes after the purpose string
* in order to get the parameter information.
*/
- if (endptr - buf <= 12)
+ if (endptr <= buf + 12)
{
png_chunk_benign_error(png_ptr, "invalid");
- return handled_error;
+ return;
}
png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
@@ -2213,7 +2158,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
(type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
{
png_chunk_benign_error(png_ptr, "invalid parameter count");
- return handled_error;
+ return;
}
else if (type >= PNG_EQUATION_LAST)
@@ -2232,7 +2177,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (params == NULL)
{
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ return;
}
/* Get pointers to the start of each parameter string. */
@@ -2250,59 +2195,76 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_free(png_ptr, params);
png_chunk_benign_error(png_ptr, "invalid data");
- return handled_error;
+ return;
}
}
png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
- (png_charp)units, params);
+ (png_charp)units, params);
- /* TODO: BUG: png_set_pCAL calls png_chunk_report which, in this case, calls
- * png_benign_error and that can error out.
- *
- * png_read_buffer needs to be allocated with space for both nparams and the
- * parameter strings. Not hard to do.
- */
png_free(png_ptr, params);
- return handled_ok;
}
-#else
-# define png_handle_pCAL NULL
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
/* Read the sCAL chunk */
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_bytep buffer;
- size_t i;
+ png_size_t i;
int state;
png_debug(1, "in png_handle_sCAL");
- png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
- length + 1);
- buffer = png_read_buffer(png_ptr, length+1);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ /* Need unit type, width, \0, height: minimum 4 bytes */
+ else if (length < 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
+ length + 1);
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
if (buffer == NULL)
{
- png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ png_crc_finish(png_ptr, length);
+ return;
}
png_crc_read(png_ptr, buffer, length);
buffer[length] = 0; /* Null terminate the last string */
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
/* Validate the unit. */
if (buffer[0] != 1 && buffer[0] != 2)
{
png_chunk_benign_error(png_ptr, "invalid unit");
- return handled_error;
+ return;
}
/* Validate the ASCII numbers, need two ASCII numbers separated by
@@ -2311,42 +2273,35 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
i = 1;
state = 0;
- if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 ||
+ if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
i >= length || buffer[i++] != 0)
png_chunk_benign_error(png_ptr, "bad width format");
- else if (PNG_FP_IS_POSITIVE(state) == 0)
+ else if (!PNG_FP_IS_POSITIVE(state))
png_chunk_benign_error(png_ptr, "non-positive width");
else
{
- size_t heighti = i;
+ png_size_t heighti = i;
state = 0;
- if (png_check_fp_number((png_const_charp)buffer, length,
- &state, &i) == 0 || i != length)
+ if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
+ i != length)
png_chunk_benign_error(png_ptr, "bad height format");
- else if (PNG_FP_IS_POSITIVE(state) == 0)
+ else if (!PNG_FP_IS_POSITIVE(state))
png_chunk_benign_error(png_ptr, "non-positive height");
else
- {
/* This is the (only) success case. */
png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
- (png_charp)buffer+1, (png_charp)buffer+heighti);
- return handled_ok;
- }
+ (png_charp)buffer+1, (png_charp)buffer+heighti);
}
-
- return handled_error;
}
-#else
-# define png_handle_sCAL NULL
#endif
#ifdef PNG_READ_tIME_SUPPORTED
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_byte buf[7];
@@ -2354,17 +2309,30 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
png_debug(1, "in png_handle_tIME");
- /* TODO: what is this doing here? It should be happened in pngread.c and
- * pngpread.c, although it could be moved to png_handle_chunk below and
- * thereby avoid some code duplication.
- */
- if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
png_ptr->mode |= PNG_AFTER_IDAT;
+ if (length != 7)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
png_crc_read(png_ptr, buf, 7);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
mod_time.second = buf[6];
mod_time.minute = buf[5];
@@ -2374,19 +2342,15 @@ png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
mod_time.year = png_get_uint_16(buf);
png_set_tIME(png_ptr, info_ptr, &mod_time);
- return handled_ok;
- PNG_UNUSED(length)
}
-#else
-# define png_handle_tIME NULL
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
/* Note: this does not properly handle chunks that are > 64K under DOS */
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
- png_text text_info;
+ png_text text_info;
png_bytep buffer;
png_charp key;
png_charp text;
@@ -2400,31 +2364,45 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
- return handled_error;
+ return;
}
if (--png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "no space in chunk cache");
- return handled_error;
+ return;
}
}
#endif
- buffer = png_read_buffer(png_ptr, length+1);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
if (buffer == NULL)
{
- png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
}
png_crc_read(png_ptr, buffer, length);
- if (png_crc_finish(png_ptr, skip) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, skip))
+ return;
key = (png_charp)buffer;
key[length] = 0;
@@ -2443,24 +2421,19 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
text_info.text = text;
text_info.text_length = strlen(text);
- if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) == 0)
- return handled_ok;
-
- png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ if (png_set_text_2(png_ptr, info_ptr, &text_info, 1))
+ png_warning(png_ptr, "Insufficient memory to process text chunk");
}
-#else
-# define png_handle_tEXt NULL
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
/* Note: this does not correctly handle chunks that are > 64K under DOS */
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_const_charp errmsg = NULL;
- png_bytep buffer;
- png_uint_32 keyword_length;
+ png_bytep buffer;
+ png_uint_32 keyword_length;
png_debug(1, "in png_handle_zTXt");
@@ -2470,35 +2443,37 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
- return handled_error;
+ return;
}
if (--png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "no space in chunk cache");
- return handled_error;
+ return;
}
}
#endif
- /* Note, "length" is sufficient here; we won't be adding
- * a null terminator later. The limit check in png_handle_chunk should be
- * sufficient.
- */
- buffer = png_read_buffer(png_ptr, length);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
if (buffer == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buffer, length);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
/* TODO: also check that the keyword contents match the spec! */
for (keyword_length = 0;
@@ -2528,50 +2503,41 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
* and text chunks.
*/
if (png_decompress_chunk(png_ptr, length, keyword_length+2,
- &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
{
png_text text;
- if (png_ptr->read_buffer == NULL)
- errmsg="Read failure in png_handle_zTXt";
- else
- {
- /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
- * except for the extra compression type byte and the fact that
- * it isn't necessarily '\0' terminated.
- */
- buffer = png_ptr->read_buffer;
- buffer[uncompressed_length+(keyword_length+2)] = 0;
+ /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
+ * for the extra compression type byte and the fact that it isn't
+ * necessarily '\0' terminated.
+ */
+ buffer = png_ptr->read_buffer;
+ buffer[uncompressed_length+(keyword_length+2)] = 0;
- text.compression = PNG_TEXT_COMPRESSION_zTXt;
- text.key = (png_charp)buffer;
- text.text = (png_charp)(buffer + keyword_length+2);
- text.text_length = uncompressed_length;
- text.itxt_length = 0;
- text.lang = NULL;
- text.lang_key = NULL;
+ text.compression = PNG_TEXT_COMPRESSION_zTXt;
+ text.key = (png_charp)buffer;
+ text.text = (png_charp)(buffer + keyword_length+2);
+ text.text_length = uncompressed_length;
+ text.itxt_length = 0;
+ text.lang = NULL;
+ text.lang_key = NULL;
- if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
- return handled_ok;
-
- errmsg = "out of memory";
- }
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1))
+ errmsg = "insufficient memory";
}
else
errmsg = png_ptr->zstream.msg;
}
- png_chunk_benign_error(png_ptr, errmsg);
- return handled_error;
+ if (errmsg != NULL)
+ png_chunk_benign_error(png_ptr, errmsg);
}
-#else
-# define png_handle_zTXt NULL
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
/* Note: this does not correctly handle chunks that are > 64K under DOS */
-static png_handle_result_code /* PRIVATE */
+void /* PRIVATE */
png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{
png_const_charp errmsg = NULL;
@@ -2586,31 +2552,37 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
- return handled_error;
+ return;
}
if (--png_ptr->user_chunk_cache_max == 1)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "no space in chunk cache");
- return handled_error;
+ return;
}
}
#endif
- buffer = png_read_buffer(png_ptr, length+1);
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
if (buffer == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
- return handled_error;
+ return;
}
png_crc_read(png_ptr, buffer, length);
- if (png_crc_finish(png_ptr, 0) != 0)
- return handled_error;
+ if (png_crc_finish(png_ptr, 0))
+ return;
/* First the keyword. */
for (prefix_length=0;
@@ -2655,14 +2627,14 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* prefix_length should now be at the trailing '\0' of the translated
* keyword, but it may already be over the end. None of this arithmetic
* can overflow because chunks are at most 2^31 bytes long, but on 16-bit
- * systems the available allocation may overflow.
+ * systems the available allocaton may overflow.
*/
++prefix_length;
- if (compressed == 0 && prefix_length <= length)
+ if (!compressed && prefix_length <= length)
uncompressed_length = length - prefix_length;
- else if (compressed != 0 && prefix_length < length)
+ else if (compressed && prefix_length < length)
{
uncompressed_length = PNG_SIZE_MAX;
@@ -2671,7 +2643,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
* iCCP and text chunks.
*/
if (png_decompress_chunk(png_ptr, length, prefix_length,
- &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
buffer = png_ptr->read_buffer;
else
@@ -2687,7 +2659,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
buffer[uncompressed_length+prefix_length] = 0;
- if (compressed == 0)
+ if (compressed)
text.compression = PNG_ITXT_COMPRESSION_NONE;
else
@@ -2700,10 +2672,8 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
text.text_length = 0;
text.itxt_length = uncompressed_length;
- if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
- return handled_ok;
-
- errmsg = "out of memory";
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1))
+ errmsg = "insufficient memory";
}
}
@@ -2712,10 +2682,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if (errmsg != NULL)
png_chunk_benign_error(png_ptr, errmsg);
- return handled_error;
}
-#else
-# define png_handle_iTXt NULL
#endif
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
@@ -2723,7 +2690,7 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
static int
png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
{
- const png_alloc_size_t limit = png_chunk_max(png_ptr);
+ png_alloc_size_t limit = PNG_SIZE_MAX;
if (png_ptr->unknown_chunk.data != NULL)
{
@@ -2731,11 +2698,21 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
png_ptr->unknown_chunk.data = NULL;
}
+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
if (length <= limit)
{
PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
/* The following is safe because of the PNG_SIZE_MAX init above */
- png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/;
+ png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
/* 'mode' is a flag array, only the bottom four bits matter here */
png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
@@ -2746,7 +2723,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
{
/* Do a 'warn' here - it is handled below. */
png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
- png_malloc_warn(png_ptr, length));
+ png_malloc_warn(png_ptr, length));
}
}
@@ -2766,14 +2743,14 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
return 1;
}
}
-#endif /* READ_UNKNOWN_CHUNKS */
+#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
/* Handle an unknown, or known but disabled, chunk */
-png_handle_result_code /*PRIVATE*/
+void /* PRIVATE */
png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 length, int keep)
+ png_uint_32 length, int keep)
{
- png_handle_result_code handled = handled_discarded; /* the default */
+ int handled = 0; /* the chunk was handled */
png_debug(1, "in png_handle_unknown");
@@ -2791,7 +2768,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
*/
# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
- keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+ keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
# endif
# endif
@@ -2800,153 +2777,154 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
*/
# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
- /* The user callback takes precedence over the chunk keep value, but the
- * keep value is still required to validate a save of a critical chunk.
- */
- if (png_ptr->read_user_chunk_fn != NULL)
- {
- if (png_cache_unknown_chunk(png_ptr, length) != 0)
+ /* The user callback takes precedence over the chunk keep value, but the
+ * keep value is still required to validate a save of a critical chunk.
+ */
+ if (png_ptr->read_user_chunk_fn != NULL)
{
- /* Callback to user unknown chunk handler */
- int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
- &png_ptr->unknown_chunk);
-
- /* ret is:
- * negative: An error occurred; png_chunk_error will be called.
- * zero: The chunk was not handled, the chunk will be discarded
- * unless png_set_keep_unknown_chunks has been used to set
- * a 'keep' behavior for this particular chunk, in which
- * case that will be used. A critical chunk will cause an
- * error at this point unless it is to be saved.
- * positive: The chunk was handled, libpng will ignore/discard it.
- */
- if (ret < 0) /* handled_error */
- png_chunk_error(png_ptr, "error in user chunk");
-
- else if (ret == 0)
+ if (png_cache_unknown_chunk(png_ptr, length))
{
- /* If the keep value is 'default' or 'never' override it, but
- * still error out on critical chunks unless the keep value is
- * 'always' While this is weird it is the behavior in 1.4.12.
- * A possible improvement would be to obey the value set for the
- * chunk, but this would be an API change that would probably
- * damage some applications.
- *
- * The png_app_warning below catches the case that matters, where
- * the application has not set specific save or ignore for this
- * chunk or global save or ignore.
+ /* Callback to user unknown chunk handler */
+ int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
+ &png_ptr->unknown_chunk);
+
+ /* ret is:
+ * negative: An error occured, png_chunk_error will be called.
+ * zero: The chunk was not handled, the chunk will be discarded
+ * unless png_set_keep_unknown_chunks has been used to set
+ * a 'keep' behavior for this particular chunk, in which
+ * case that will be used. A critical chunk will cause an
+ * error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
*/
- if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+
+ else if (ret == 0)
{
-# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
- if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
+ /* If the keep value is 'default' or 'never' override it, but
+ * still error out on critical chunks unless the keep value is
+ * 'always' While this is weird it is the behavior in 1.4.12.
+ * A possible improvement would be to obey the value set for the
+ * chunk, but this would be an API change that would probably
+ * damage some applications.
+ *
+ * The png_app_warning below catches the case that matters, where
+ * the application has not set specific save or ignore for this
+ * chunk or global save or ignore.
+ */
+ if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
{
- png_chunk_warning(png_ptr, "Saving unknown chunk:");
- png_app_warning(png_ptr,
- "forcing save of an unhandled chunk;"
- " please call png_set_keep_unknown_chunks");
- /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
+ {
+ png_chunk_warning(png_ptr, "Saving unknown chunk:");
+ png_app_warning(png_ptr,
+ "forcing save of an unhandled chunk;"
+ " please call png_set_keep_unknown_chunks");
+ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+ }
+# endif
+ keep = PNG_HANDLE_CHUNK_IF_SAFE;
}
-# endif
- keep = PNG_HANDLE_CHUNK_IF_SAFE;
+ }
+
+ else /* chunk was handled */
+ {
+ handled = 1;
+ /* Critical chunks can be safely discarded at this point. */
+ keep = PNG_HANDLE_CHUNK_NEVER;
}
}
- else /* chunk was handled */
- {
- handled = handled_ok;
- /* Critical chunks can be safely discarded at this point. */
- keep = PNG_HANDLE_CHUNK_NEVER;
- }
+ else
+ keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
}
else
- keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
- }
-
- else
- /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
-# endif /* READ_USER_CHUNKS */
+ /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
+# endif /* PNG_READ_USER_CHUNKS_SUPPORTED */
# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
- {
- /* keep is currently just the per-chunk setting, if there was no
- * setting change it to the global default now (not that this may
- * still be AS_DEFAULT) then obtain the cache of the chunk if required,
- * if not simply skip the chunk.
- */
- if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
- keep = png_ptr->unknown_default;
-
- if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
- PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
{
- if (png_cache_unknown_chunk(png_ptr, length) == 0)
- keep = PNG_HANDLE_CHUNK_NEVER;
- }
+ /* keep is currently just the per-chunk setting, if there was no
+ * setting change it to the global default now (not that this may
+ * still be AS_DEFAULT) then obtain the cache of the chunk if required,
+ * if not simply skip the chunk.
+ */
+ if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
+ keep = png_ptr->unknown_default;
- else
- png_crc_finish(png_ptr, length);
- }
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+ {
+ if (!png_cache_unknown_chunk(png_ptr, length))
+ keep = PNG_HANDLE_CHUNK_NEVER;
+ }
+
+ else
+ png_crc_finish(png_ptr, length);
+ }
# else
# ifndef PNG_READ_USER_CHUNKS_SUPPORTED
# error no method to support READ_UNKNOWN_CHUNKS
# endif
- {
- /* If here there is no read callback pointer set and no support is
- * compiled in to just save the unknown chunks, so simply skip this
- * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then
- * the app has erroneously asked for unknown chunk saving when there
- * is no support.
- */
- if (keep > PNG_HANDLE_CHUNK_NEVER)
- png_app_error(png_ptr, "no unknown chunk support available");
+ {
+ /* If here there is no read callback pointer set and no support is
+ * compiled in to just save the unknown chunks, so simply skip this
+ * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then
+ * the app has erroneously asked for unknown chunk saving when there
+ * is no support.
+ */
+ if (keep > PNG_HANDLE_CHUNK_NEVER)
+ png_app_error(png_ptr, "no unknown chunk support available");
- png_crc_finish(png_ptr, length);
- }
+ png_crc_finish(png_ptr, length);
+ }
# endif
# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
- /* Now store the chunk in the chunk list if appropriate, and if the limits
- * permit it.
- */
- if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
- (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
- PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
- {
-# ifdef PNG_USER_LIMITS_SUPPORTED
- switch (png_ptr->user_chunk_cache_max)
+ /* Now store the chunk in the chunk list if appropriate, and if the limits
+ * permit it.
+ */
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
{
- case 2:
- png_ptr->user_chunk_cache_max = 1;
- png_chunk_benign_error(png_ptr, "no space in chunk cache");
- /* FALLTHROUGH */
- case 1:
- /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
- * chunk being skipped, now there will be a hard error below.
- */
- break;
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ switch (png_ptr->user_chunk_cache_max)
+ {
+ case 2:
+ png_ptr->user_chunk_cache_max = 1;
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ /* FALL THROUGH */
+ case 1:
+ /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
+ * chunk being skipped, now there will be a hard error below.
+ */
+ break;
- default: /* not at limit */
- --(png_ptr->user_chunk_cache_max);
- /* FALLTHROUGH */
- case 0: /* no limit */
-# endif /* USER_LIMITS */
- /* Here when the limit isn't reached or when limits are compiled
- * out; store the chunk.
- */
- png_set_unknown_chunks(png_ptr, info_ptr,
- &png_ptr->unknown_chunk, 1);
- handled = handled_saved;
-# ifdef PNG_USER_LIMITS_SUPPORTED
- break;
+ default: /* not at limit */
+ --(png_ptr->user_chunk_cache_max);
+ /* FALL THROUGH */
+ case 0: /* no limit */
+# endif /* PNG_USER_LIMITS_SUPPORTED */
+ /* Here when the limit isn't reached or when limits are compiled
+ * out; store the chunk.
+ */
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ handled = 1;
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ break;
+ }
+# endif
}
-# endif
- }
-# else /* no store support: the chunk must be handled by the user callback */
- PNG_UNUSED(info_ptr)
+# else /* no store support! */
+ PNG_UNUSED(info_ptr)
+# error untested code (reading unknown chunks with no store support)
# endif
/* Regardless of the error handling below the cached data (if any) can be
@@ -2962,272 +2940,43 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
png_crc_finish(png_ptr, length);
PNG_UNUSED(info_ptr)
PNG_UNUSED(keep)
-#endif /* !READ_UNKNOWN_CHUNKS */
+#endif /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
/* Check for unhandled critical chunks */
- if (handled < handled_saved && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
+ if (!handled && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
png_chunk_error(png_ptr, "unhandled critical chunk");
-
- return handled;
}
-/* APNG handling: the minimal implementation of APNG handling in libpng 1.6
- * requires that those significant applications which already handle APNG not
- * get hosed. To do this ensure the code here will have to ensure than APNG
- * data by default (at least in 1.6) gets stored in the unknown chunk list.
- * Maybe this can be relaxed in a few years but at present it's just the only
- * safe way.
- *
- * ATM just cause unknown handling for all three chunks:
+/* This function is called to verify that a chunk name is valid.
+ * This function can't have the "critical chunk check" incorporated
+ * into it, since in the future we will need to be able to call user
+ * functions to handle unknown critical chunks after we check that
+ * the chunk name itself is valid.
*/
-#define png_handle_acTL NULL
-#define png_handle_fcTL NULL
-#define png_handle_fdAT NULL
-/*
- * 1.6.47: This is the new table driven interface to all the chunk handling.
+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
*
- * The table describes the PNG standard rules for **reading** known chunks -
- * every chunk which has an entry in PNG_KNOWN_CHUNKS. The table contains an
- * entry for each PNG_INDEX_cHNK describing the rules.
- *
- * In this initial version the only information in the entry is the
- * png_handle_cHNK function for the chunk in question. When chunk support is
- * compiled out the entry will be NULL.
+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
*/
-static const struct
+
+void /* PRIVATE */
+png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
{
- png_handle_result_code (*handler)(
- png_structrp, png_inforp, png_uint_32 length);
- /* A chunk-specific 'handler', NULL if the chunk is not supported in this
- * build.
- */
+ int i;
- /* Crushing these values helps on modern 32-bit architectures because the
- * pointer and the following bit fields both end up requiring 32 bits.
- * Typically this will halve the table size. On 64-bit architectures the
- * table entries will typically be 8 bytes.
- */
- png_uint_32 max_length :12; /* Length min, max in bytes */
- png_uint_32 min_length :8;
- /* Length errors on critical chunks have special handling to preserve the
- * existing behaviour in libpng 1.6. Anciallary chunks are checked below
- * and produce a 'benign' error.
- */
- png_uint_32 pos_before :4; /* PNG_HAVE_ values chunk must precede */
- png_uint_32 pos_after :4; /* PNG_HAVE_ values chunk must follow */
- /* NOTE: PLTE, tRNS and bKGD require special handling which depends on
- * the colour type of the base image.
- */
- png_uint_32 multiple :1; /* Multiple occurences permitted */
- /* This is enabled for PLTE because PLTE may, in practice, be optional */
-}
-read_chunks[PNG_INDEX_unknown] =
-{
- /* Definitions as above but done indirectly by #define so that
- * PNG_KNOWN_CHUNKS can be used safely to build the table in order.
- *
- * Each CDcHNK definition lists the values for the parameters **after**
- * the first, 'handler', function. 'handler' is NULL when the chunk has no
- * compiled in support.
- */
-# define NoCheck 0x801U /* Do not check the maximum length */
-# define Limit 0x802U /* Limit to png_chunk_max bytes */
-# define LKMin 3U+LZ77Min /* Minimum length of keyword+LZ77 */
+ png_debug(1, "in png_check_chunk_name");
-#define hIHDR PNG_HAVE_IHDR
-#define hPLTE PNG_HAVE_PLTE
-#define hIDAT PNG_HAVE_IDAT
- /* For the two chunks, tRNS and bKGD which can occur in PNGs without a PLTE
- * but must occur after the PLTE use this and put the check in the handler
- * routine for colour mapped images were PLTE is required. Also put a check
- * in PLTE for other image types to drop the PLTE if tRNS or bKGD have been
- * seen.
- */
-#define hCOL (PNG_HAVE_PLTE|PNG_HAVE_IDAT)
- /* Used for the decoding chunks which must be before PLTE. */
-#define aIDAT PNG_AFTER_IDAT
-
- /* Chunks from W3C PNG v3: */
- /* cHNK max_len, min, before, after, multiple */
-# define CDIHDR 13U, 13U, hIHDR, 0, 0
-# define CDPLTE NoCheck, 0U, 0, hIHDR, 1
- /* PLTE errors are only critical for colour-map images, consequently the
- * hander does all the checks.
- */
-# define CDIDAT NoCheck, 0U, aIDAT, hIHDR, 1
-# define CDIEND NoCheck, 0U, 0, aIDAT, 0
- /* Historically data was allowed in IEND */
-# define CDtRNS 256U, 0U, hIDAT, hIHDR, 0
-# define CDcHRM 32U, 32U, hCOL, hIHDR, 0
-# define CDgAMA 4U, 4U, hCOL, hIHDR, 0
-# define CDiCCP NoCheck, LKMin, hCOL, hIHDR, 0
-# define CDsBIT 4U, 1U, hCOL, hIHDR, 0
-# define CDsRGB 1U, 1U, hCOL, hIHDR, 0
-# define CDcICP 4U, 4U, hCOL, hIHDR, 0
-# define CDmDCV 24U, 24U, hCOL, hIHDR, 0
-# define CDeXIf Limit, 4U, 0, hIHDR, 0
-# define CDcLLI 8U, 8U, hCOL, hIHDR, 0
-# define CDtEXt NoCheck, 2U, 0, hIHDR, 1
- /* Allocates 'length+1'; checked in the handler */
-# define CDzTXt Limit, LKMin, 0, hIHDR, 1
-# define CDiTXt NoCheck, 6U, 0, hIHDR, 1
- /* Allocates 'length+1'; checked in the handler */
-# define CDbKGD 6U, 1U, hIDAT, hIHDR, 0
-# define CDhIST 1024U, 0U, hPLTE, hIHDR, 0
-# define CDpHYs 9U, 9U, hIDAT, hIHDR, 0
-# define CDsPLT NoCheck, 3U, hIDAT, hIHDR, 1
- /* Allocates 'length+1'; checked in the handler */
-# define CDtIME 7U, 7U, 0, hIHDR, 0
-# define CDacTL 8U, 8U, hIDAT, hIHDR, 0
-# define CDfcTL 25U, 26U, 0, hIHDR, 1
-# define CDfdAT Limit, 4U, hIDAT, hIHDR, 1
- /* Supported chunks from PNG extensions 1.5.0, NYI so limit */
-# define CDoFFs 9U, 9U, hIDAT, hIHDR, 0
-# define CDpCAL NoCheck, 14U, hIDAT, hIHDR, 0
- /* Allocates 'length+1'; checked in the handler */
-# define CDsCAL Limit, 4U, hIDAT, hIHDR, 0
- /* Allocates 'length+1'; checked in the handler */
-
-# define PNG_CHUNK(cHNK, index) { png_handle_ ## cHNK, CD ## cHNK },
- PNG_KNOWN_CHUNKS
-# undef PNG_CHUNK
-};
-
-
-static png_index
-png_chunk_index_from_name(png_uint_32 chunk_name)
-{
- /* For chunk png_cHNK return PNG_INDEX_cHNK. Return PNG_INDEX_unknown if
- * chunk_name is not known. Notice that in a particular build "known" does
- * not necessarily mean "supported", although the inverse applies.
- */
- switch (chunk_name)
+ for (i=1; i<=4; ++i)
{
-# define PNG_CHUNK(cHNK, index)\
- case png_ ## cHNK: return PNG_INDEX_ ## cHNK; /* == index */
+ int c = chunk_name & 0xff;
- PNG_KNOWN_CHUNKS
+ if (c < 65 || c > 122 || (c > 90 && c < 97))
+ png_chunk_error(png_ptr, "invalid chunk type");
-# undef PNG_CHUNK
-
- default: return PNG_INDEX_unknown;
+ chunk_name >>= 8;
}
}
-png_handle_result_code /*PRIVATE*/
-png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
-{
- /* CSE: these things don't change, these autos are just to save typing and
- * make the code more clear.
- */
- const png_uint_32 chunk_name = png_ptr->chunk_name;
- const png_index chunk_index = png_chunk_index_from_name(chunk_name);
-
- png_handle_result_code handled = handled_error;
- png_const_charp errmsg = NULL;
-
- /* Is this a known chunk? If not there are no checks performed here;
- * png_handle_unknown does the correct checks. This means that the values
- * for known but unsupported chunks in the above table are not used here
- * however the chunks_seen fields in png_struct are still set.
- */
- if (chunk_index == PNG_INDEX_unknown ||
- read_chunks[chunk_index].handler == NULL)
- {
- handled = png_handle_unknown(
- png_ptr, info_ptr, length, PNG_HANDLE_CHUNK_AS_DEFAULT);
- }
-
- /* First check the position. The first check is historical; the stream must
- * start with IHDR and anything else causes libpng to give up immediately.
- */
- else if (chunk_index != PNG_INDEX_IHDR &&
- (png_ptr->mode & PNG_HAVE_IHDR) == 0)
- png_chunk_error(png_ptr, "missing IHDR"); /* NORETURN */
-
- /* Before all the pos_before chunks, after all the pos_after chunks. */
- else if (((png_ptr->mode & read_chunks[chunk_index].pos_before) != 0) ||
- ((png_ptr->mode & read_chunks[chunk_index].pos_after) !=
- read_chunks[chunk_index].pos_after))
- {
- errmsg = "out of place";
- }
-
- /* Now check for duplicates: duplicated critical chunks also produce a
- * full error.
- */
- else if (read_chunks[chunk_index].multiple == 0 &&
- png_file_has_chunk(png_ptr, chunk_index))
- {
- errmsg = "duplicate";
- }
-
- else if (length < read_chunks[chunk_index].min_length)
- errmsg = "too short";
- else
- {
- /* NOTE: apart from IHDR the critical chunks (PLTE, IDAT and IEND) are set
- * up above not to do any length checks.
- *
- * The png_chunk_max check ensures that the variable length chunks are
- * always checked at this point for being within the system allocation
- * limits.
- */
- unsigned max_length = read_chunks[chunk_index].max_length;
-
- switch (max_length)
- {
- case Limit:
- /* png_read_chunk_header has already png_error'ed chunks with a
- * length exceeding the 31-bit PNG limit, so just check the memory
- * limit:
- */
- if (length <= png_chunk_max(png_ptr))
- goto MeetsLimit;
-
- errmsg = "length exceeds libpng limit";
- break;
-
- default:
- if (length <= max_length)
- goto MeetsLimit;
-
- errmsg = "too long";
- break;
-
- case NoCheck:
- MeetsLimit:
- handled = read_chunks[chunk_index].handler(
- png_ptr, info_ptr, length);
- break;
- }
- }
-
- /* If there was an error or the chunk was simply skipped it is not counted as
- * 'seen'.
- */
- if (errmsg != NULL)
- {
- if (PNG_CHUNK_CRITICAL(chunk_name)) /* stop immediately */
- png_chunk_error(png_ptr, errmsg);
- else /* ancillary chunk */
- {
- /* The chunk data is skipped: */
- png_crc_finish(png_ptr, length);
- png_chunk_benign_error(png_ptr, errmsg);
- }
- }
-
- else if (handled >= handled_saved)
- {
- if (chunk_index != PNG_INDEX_unknown)
- png_file_add_chunk(png_ptr, chunk_index);
- }
-
- return handled;
-}
-
/* Combines the row recently read in with the existing pixels in the row. This
* routine takes care of alpha and transparency if requested. This routine also
* handles the two methods of progressive display of interlaced images,
@@ -3240,7 +2989,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
{
unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
png_const_bytep sp = png_ptr->row_buf + 1;
- png_alloc_size_t row_width = png_ptr->width;
+ png_uint_32 row_width = png_ptr->width;
unsigned int pass = png_ptr->pass;
png_bytep end_ptr = 0;
png_byte end_byte = 0;
@@ -3277,13 +3026,12 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
end_byte = *end_ptr;
# ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
- /* little-endian byte */
- end_mask = (unsigned int)(0xff << end_mask);
+ if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
+ end_mask = 0xff << end_mask;
- else /* big-endian byte */
+ else /* big-endian byte */
# endif
- end_mask = 0xff >> end_mask;
+ end_mask = 0xff >> end_mask;
/* end_mask is now the bits to *keep* from the destination row */
}
@@ -3294,11 +3042,10 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
* pass.
*/
#ifdef PNG_READ_INTERLACING_SUPPORTED
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0 &&
- pass < 6 && (display == 0 ||
- /* The following copies everything for 'display' on passes 0, 2 and 4. */
- (display == 1 && (pass & 1) != 0)))
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
+ pass < 6 && (display == 0 ||
+ /* The following copies everything for 'display' on passes 0, 2 and 4. */
+ (display == 1 && (pass & 1) != 0)))
{
/* Narrow images may have no bits in a pass; the caller should handle
* this, but this test is cheap:
@@ -3394,14 +3141,14 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
-# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) }
+# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
/* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
* then pass:
*/
- static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
+ static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
{
/* Little-endian byte masks for PACKSWAP */
{ S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
@@ -3412,7 +3159,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
/* display_mask has only three entries for the odd passes, so index by
* pass>>1.
*/
- static const png_uint_32 display_mask[2][3][3] =
+ static PNG_CONST png_uint_32 display_mask[2][3][3] =
{
/* Little-endian byte masks for PACKSWAP */
{ B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
@@ -3430,10 +3177,10 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
*/
# define MASK(pass,depth,display,png)\
((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
-#endif /* !USE_COMPILE_TIME_MASKS */
+#endif /* !PNG_USE_COMPILE_TIME_MASKS */
/* Use the appropriate mask to copy the required bits. In some cases
- * the byte mask will be 0 or 0xff; optimize these cases. row_width is
+ * the byte mask will be 0 or 0xff, optimize these cases. row_width is
* the number of pixels, but the code copies bytes, so it is necessary
* to special case the end.
*/
@@ -3441,12 +3188,12 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
png_uint_32 mask;
# ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
- mask = MASK(pass, pixel_depth, display, 0);
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ mask = MASK(pass, pixel_depth, display, 0);
- else
+ else
# endif
- mask = MASK(pass, pixel_depth, display, 1);
+ mask = MASK(pass, pixel_depth, display, 1);
for (;;)
{
@@ -3505,7 +3252,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
}
/* Work out the bytes to copy. */
- if (display != 0)
+ if (display)
{
/* When doing the 'block' algorithm the pixel in the pass gets
* replicated to adjacent pixels. This is why the even (0,2,4,6)
@@ -3515,7 +3262,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
/* But don't allow this number to exceed the actual row width. */
if (bytes_to_copy > row_width)
- bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+ bytes_to_copy = row_width;
}
else /* normal row; Adam7 only ever gives us one pixel to copy. */
@@ -3553,7 +3300,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
*/
do
{
- dp[0] = sp[0]; dp[1] = sp[1];
+ dp[0] = sp[0], dp[1] = sp[1];
if (row_width <= bytes_to_jump)
return;
@@ -3572,9 +3319,9 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
/* This can only be the RGB case, so each copy is exactly one
* pixel and it is not necessary to check for a partial copy.
*/
- for (;;)
+ for(;;)
{
- dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
+ dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
if (row_width <= bytes_to_jump)
return;
@@ -3592,24 +3339,24 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
* wide bytes_to_copy either - use the memcpy there.
*/
if (bytes_to_copy < 16 /*else use memcpy*/ &&
- png_isaligned(dp, png_uint_16) &&
- png_isaligned(sp, png_uint_16) &&
- bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
- bytes_to_jump % (sizeof (png_uint_16)) == 0)
+ png_isaligned(dp, png_uint_16) &&
+ png_isaligned(sp, png_uint_16) &&
+ bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_16)) == 0)
{
/* Everything is aligned for png_uint_16 copies, but try for
* png_uint_32 first.
*/
if (png_isaligned(dp, png_uint_32) &&
- png_isaligned(sp, png_uint_32) &&
- bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
- bytes_to_jump % (sizeof (png_uint_32)) == 0)
+ png_isaligned(sp, png_uint_32) &&
+ bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_32)) == 0)
{
png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
png_const_uint_32p sp32 = png_aligncastconst(
- png_const_uint_32p, sp);
+ png_const_uint_32p, sp);
size_t skip = (bytes_to_jump-bytes_to_copy) /
- (sizeof (png_uint_32));
+ (sizeof (png_uint_32));
do
{
@@ -3681,7 +3428,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
return;
}
}
-#endif /* ALIGN_TYPE code */
+#endif /* PNG_ALIGN_ code */
/* The true default - use a memcpy: */
for (;;)
@@ -3695,7 +3442,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
dp += bytes_to_jump;
row_width -= bytes_to_jump;
if (bytes_to_copy > row_width)
- bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+ bytes_to_copy = row_width;
}
}
@@ -3705,7 +3452,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
/* Here if pixel_depth < 8 to check 'end_ptr' below. */
}
else
-#endif /* READ_INTERLACING */
+#endif
/* If here then the switch above wasn't used so just memcpy the whole row
* from the temporary row buffer (notice that this overwrites the end of the
@@ -3721,8 +3468,12 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
#ifdef PNG_READ_INTERLACING_SUPPORTED
void /* PRIVATE */
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
- png_uint_32 transformations /* Because these may affect the byte layout */)
+ png_uint_32 transformations /* Because these may affect the byte layout */)
{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* Offset to next interlace block */
+ static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
png_debug(1, "in png_do_read_interlace");
if (row != NULL && row_info != NULL)
{
@@ -3734,21 +3485,20 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
{
case 1:
{
- png_bytep sp = row + (size_t)((row_info->width - 1) >> 3);
- png_bytep dp = row + (size_t)((final_width - 1) >> 3);
- unsigned int sshift, dshift;
- unsigned int s_start, s_end;
- int s_inc;
- int jstop = (int)png_pass_inc[pass];
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
png_byte v;
png_uint_32 i;
int j;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((transformations & PNG_PACKSWAP) != 0)
+ if (transformations & PNG_PACKSWAP)
{
- sshift = ((row_info->width + 7) & 0x07);
- dshift = ((final_width + 7) & 0x07);
+ sshift = (int)((row_info->width + 7) & 0x07);
+ dshift = (int)((final_width + 7) & 0x07);
s_start = 7;
s_end = 0;
s_inc = -1;
@@ -3757,8 +3507,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
else
#endif
{
- sshift = 7 - ((row_info->width + 7) & 0x07);
- dshift = 7 - ((final_width + 7) & 0x07);
+ sshift = 7 - (int)((row_info->width + 7) & 0x07);
+ dshift = 7 - (int)((final_width + 7) & 0x07);
s_start = 0;
s_end = 7;
s_inc = 1;
@@ -3770,7 +3520,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
- tmp |= (unsigned int)(v << dshift);
+ tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
if (dshift == s_end)
@@ -3780,7 +3530,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- dshift = (unsigned int)((int)dshift + s_inc);
+ dshift += s_inc;
}
if (sshift == s_end)
@@ -3790,7 +3540,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- sshift = (unsigned int)((int)sshift + s_inc);
+ sshift += s_inc;
}
break;
}
@@ -3799,17 +3549,16 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
{
png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
- unsigned int sshift, dshift;
- unsigned int s_start, s_end;
- int s_inc;
- int jstop = (int)png_pass_inc[pass];
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
png_uint_32 i;
#ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((transformations & PNG_PACKSWAP) != 0)
+ if (transformations & PNG_PACKSWAP)
{
- sshift = (((row_info->width + 3) & 0x03) << 1);
- dshift = (((final_width + 3) & 0x03) << 1);
+ sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+ dshift = (int)(((final_width + 3) & 0x03) << 1);
s_start = 6;
s_end = 0;
s_inc = -2;
@@ -3818,8 +3567,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
else
#endif
{
- sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
- dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
+ sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
s_start = 0;
s_end = 6;
s_inc = 2;
@@ -3834,7 +3583,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
- tmp |= (unsigned int)(v << dshift);
+ tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
if (dshift == s_end)
@@ -3844,7 +3593,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- dshift = (unsigned int)((int)dshift + s_inc);
+ dshift += s_inc;
}
if (sshift == s_end)
@@ -3854,26 +3603,25 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- sshift = (unsigned int)((int)sshift + s_inc);
+ sshift += s_inc;
}
break;
}
case 4:
{
- png_bytep sp = row + (size_t)((row_info->width - 1) >> 1);
- png_bytep dp = row + (size_t)((final_width - 1) >> 1);
- unsigned int sshift, dshift;
- unsigned int s_start, s_end;
- int s_inc;
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
png_uint_32 i;
- int jstop = (int)png_pass_inc[pass];
+ int jstop = png_pass_inc[pass];
#ifdef PNG_READ_PACKSWAP_SUPPORTED
- if ((transformations & PNG_PACKSWAP) != 0)
+ if (transformations & PNG_PACKSWAP)
{
- sshift = (((row_info->width + 1) & 0x01) << 2);
- dshift = (((final_width + 1) & 0x01) << 2);
+ sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+ dshift = (int)(((final_width + 1) & 0x01) << 2);
s_start = 4;
s_end = 0;
s_inc = -4;
@@ -3882,8 +3630,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
else
#endif
{
- sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
- dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
+ sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
s_start = 0;
s_end = 4;
s_inc = 4;
@@ -3897,7 +3645,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
for (j = 0; j < jstop; j++)
{
unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
- tmp |= (unsigned int)(v << dshift);
+ tmp |= v << dshift;
*dp = (png_byte)(tmp & 0xff);
if (dshift == s_end)
@@ -3907,7 +3655,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- dshift = (unsigned int)((int)dshift + s_inc);
+ dshift += s_inc;
}
if (sshift == s_end)
@@ -3917,26 +3665,26 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
}
else
- sshift = (unsigned int)((int)sshift + s_inc);
+ sshift += s_inc;
}
break;
}
default:
{
- size_t pixel_bytes = (row_info->pixel_depth >> 3);
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
- png_bytep sp = row + (size_t)(row_info->width - 1)
+ png_bytep sp = row + (png_size_t)(row_info->width - 1)
* pixel_bytes;
- png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes;
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
- int jstop = (int)png_pass_inc[pass];
+ int jstop = png_pass_inc[pass];
png_uint_32 i;
for (i = 0; i < row_info->width; i++)
{
- png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
+ png_byte v[8];
int j;
memcpy(v, sp, pixel_bytes);
@@ -3960,14 +3708,14 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
PNG_UNUSED(transformations) /* Silence compiler warning */
#endif
}
-#endif /* READ_INTERLACING */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
static void
png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
- size_t i;
- size_t istop = row_info->rowbytes;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
png_bytep rp = row + bpp;
@@ -3982,10 +3730,10 @@ png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
static void
png_read_filter_row_up(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
- size_t i;
- size_t istop = row_info->rowbytes;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
png_bytep rp = row;
png_const_bytep pp = prev_row;
@@ -3998,13 +3746,13 @@ png_read_filter_row_up(png_row_infop row_info, png_bytep row,
static void
png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
- size_t i;
+ png_size_t i;
png_bytep rp = row;
png_const_bytep pp = prev_row;
unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
- size_t istop = row_info->rowbytes - bpp;
+ png_size_t istop = row_info->rowbytes - bpp;
for (i = 0; i < bpp; i++)
{
@@ -4025,7 +3773,7 @@ png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
static void
png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
png_bytep rp_end = row + row_info->rowbytes;
int a, c;
@@ -4046,23 +3794,20 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
p = b - c;
pc = a - c;
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
+# ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+# else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+# endif
/* Find the best predictor, the least of pa, pb, pc favoring the earlier
* ones in the case of a tie.
*/
- if (pb < pa)
- {
- pa = pb; a = b;
- }
+ if (pb < pa) pa = pb, a = b;
if (pc < pa) a = c;
/* Calculate the current pixel in a, and move the previous row pixel to c
@@ -4076,9 +3821,9 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
static void
png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row)
+ png_const_bytep prev_row)
{
- unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ int bpp = (row_info->pixel_depth + 7) >> 3;
png_bytep rp_end = row + bpp;
/* Process the first pixel in the row completely (this is the same as 'up'
@@ -4091,7 +3836,7 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
}
/* Remainder */
- rp_end = rp_end + (row_info->rowbytes - bpp);
+ rp_end += row_info->rowbytes - bpp;
while (row < rp_end)
{
@@ -4104,22 +3849,20 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
p = b - c;
pc = a - c;
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
+# ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+# else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+# endif
- if (pb < pa)
- {
- pa = pb; a = b;
- }
+ if (pb < pa) pa = pb, a = b;
if (pc < pa) a = c;
+ c = b;
a += *row;
*row++ = (png_byte)a;
}
@@ -4127,8 +3870,7 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
static void
png_init_filter_functions(png_structrp pp)
- /* This function is called once for every PNG image (except for PNG images
- * that only use PNG_FILTER_VALUE_NONE for all rows) to set the
+ /* This function is called once for every PNG image to set the
* implementations required to reverse the filtering of PNG rows. Reversing
* the filter is the first transformation performed on the row data. It is
* performed in place, therefore an implementation can be selected based on
@@ -4164,25 +3906,22 @@ png_init_filter_functions(png_structrp pp)
void /* PRIVATE */
png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
- png_const_bytep prev_row, int filter)
+ png_const_bytep prev_row, int filter)
{
/* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
* PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
* implementations. See png_init_filter_functions above.
*/
+ if (pp->read_filter[0] == NULL)
+ png_init_filter_functions(pp);
if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
- {
- if (pp->read_filter[0] == NULL)
- png_init_filter_functions(pp);
-
pp->read_filter[filter-1](row_info, row, prev_row);
- }
}
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
void /* PRIVATE */
png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
- png_alloc_size_t avail_out)
+ png_alloc_size_t avail_out)
{
/* Loop reading IDATs and decompressing the result into output[avail_out] */
png_ptr->zstream.next_out = output;
@@ -4215,9 +3954,6 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
avail_in = png_ptr->IDAT_read_size;
- if (avail_in > png_chunk_max(png_ptr))
- avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr);
-
if (avail_in > png_ptr->idat_size)
avail_in = (uInt)png_ptr->idat_size;
@@ -4225,13 +3961,8 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
* to minimize memory usage by causing lots of re-allocs, but
* realistically doing IDAT_read_size re-allocs is not likely to be a
* big problem.
- *
- * An error here corresponds to the system being out of memory.
*/
- buffer = png_read_buffer(png_ptr, avail_in);
-
- if (buffer == NULL)
- png_chunk_error(png_ptr, "out of memory");
+ buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
png_crc_read(png_ptr, buffer, avail_in);
png_ptr->idat_size -= avail_in;
@@ -4265,7 +3996,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
*
* TODO: deal more elegantly with truncated IDAT lists.
*/
- ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);
+ ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
/* Take the unconsumed output back. */
if (output != NULL)
@@ -4325,7 +4056,7 @@ png_read_finish_IDAT(png_structrp png_ptr)
* read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
* may still remain to be consumed.
*/
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
{
/* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
* the compressed stream, but the stream may be damaged too, so even after
@@ -4337,7 +4068,7 @@ png_read_finish_IDAT(png_structrp png_ptr)
/* Now clear everything out for safety; the following may not have been
* done.
*/
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
{
png_ptr->mode |= PNG_AFTER_IDAT;
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
@@ -4368,12 +4099,29 @@ png_read_finish_IDAT(png_structrp png_ptr)
void /* PRIVATE */
png_read_finish_row(png_structrp png_ptr)
{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
png_debug(1, "in png_read_finish_row");
png_ptr->row_number++;
if (png_ptr->row_number < png_ptr->num_rows)
return;
- if (png_ptr->interlaced != 0)
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
@@ -4394,7 +4142,7 @@ png_read_finish_row(png_structrp png_ptr)
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
- if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ if (!(png_ptr->transformations & PNG_INTERLACE))
{
png_ptr->num_rows = (png_ptr->height +
png_pass_yinc[png_ptr->pass] - 1 -
@@ -4410,26 +4158,44 @@ png_read_finish_row(png_structrp png_ptr)
if (png_ptr->pass < 7)
return;
}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
/* Here after at the end of the last row of the last pass. */
png_read_finish_IDAT(png_ptr);
}
-#endif /* SEQUENTIAL_READ */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
void /* PRIVATE */
png_read_start_row(png_structrp png_ptr)
{
- unsigned int max_pixel_depth;
- size_t row_bytes;
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int max_pixel_depth;
+ png_size_t row_bytes;
png_debug(1, "in png_read_start_row");
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_init_read_transformations(png_ptr);
#endif
- if (png_ptr->interlaced != 0)
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
{
- if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ if (!(png_ptr->transformations & PNG_INTERLACE))
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
png_pass_ystart[0]) / png_pass_yinc[0];
@@ -4443,14 +4209,15 @@ png_read_start_row(png_structrp png_ptr)
}
else
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
{
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = png_ptr->width;
}
- max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
+ max_pixel_depth = png_ptr->pixel_depth;
- /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
+ /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
* calculations to calculate the final pixel depth, then
* png_do_read_transforms actually does the transforms. This means that the
* code which effectively calculates this value is actually repeated in three
@@ -4461,16 +4228,16 @@ png_read_start_row(png_structrp png_ptr)
* TODO: fix this.
*/
#ifdef PNG_READ_PACK_SUPPORTED
- if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8)
+ if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
max_pixel_depth = 8;
#endif
#ifdef PNG_READ_EXPAND_SUPPORTED
- if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ if (png_ptr->transformations & PNG_EXPAND)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
- if (png_ptr->num_trans != 0)
+ if (png_ptr->num_trans)
max_pixel_depth = 32;
else
@@ -4482,13 +4249,13 @@ png_read_start_row(png_structrp png_ptr)
if (max_pixel_depth < 8)
max_pixel_depth = 8;
- if (png_ptr->num_trans != 0)
+ if (png_ptr->num_trans)
max_pixel_depth *= 2;
}
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
- if (png_ptr->num_trans != 0)
+ if (png_ptr->num_trans)
{
max_pixel_depth *= 4;
max_pixel_depth /= 3;
@@ -4498,25 +4265,25 @@ png_read_start_row(png_structrp png_ptr)
#endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED
- if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
+ if (png_ptr->transformations & PNG_EXPAND_16)
{
-# ifdef PNG_READ_EXPAND_SUPPORTED
- /* In fact it is an error if it isn't supported, but checking is
- * the safe way.
- */
- if ((png_ptr->transformations & PNG_EXPAND) != 0)
- {
- if (png_ptr->bit_depth < 16)
- max_pixel_depth *= 2;
- }
- else
-# endif
- png_ptr->transformations &= ~PNG_EXPAND_16;
+# ifdef PNG_READ_EXPAND_SUPPORTED
+ /* In fact it is an error if it isn't supported, but checking is
+ * the safe way.
+ */
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->bit_depth < 16)
+ max_pixel_depth *= 2;
+ }
+ else
+# endif
+ png_ptr->transformations &= ~PNG_EXPAND_16;
}
#endif
#ifdef PNG_READ_FILLER_SUPPORTED
- if ((png_ptr->transformations & (PNG_FILLER)) != 0)
+ if (png_ptr->transformations & (PNG_FILLER))
{
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
{
@@ -4540,15 +4307,14 @@ png_read_start_row(png_structrp png_ptr)
#endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
- if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
{
if (
#ifdef PNG_READ_EXPAND_SUPPORTED
- (png_ptr->num_trans != 0 &&
- (png_ptr->transformations & PNG_EXPAND) != 0) ||
+ (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
#endif
#ifdef PNG_READ_FILLER_SUPPORTED
- (png_ptr->transformations & (PNG_FILLER)) != 0 ||
+ (png_ptr->transformations & (PNG_FILLER)) ||
#endif
png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
@@ -4581,9 +4347,9 @@ png_read_start_row(png_structrp png_ptr)
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
{
- unsigned int user_pixel_depth = png_ptr->user_transform_depth *
+ int user_pixel_depth = png_ptr->user_transform_depth *
png_ptr->user_transform_channels;
if (user_pixel_depth > max_pixel_depth)
@@ -4605,7 +4371,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
* for safety's sake
*/
row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
- 1 + ((max_pixel_depth + 7) >> 3U);
+ 1 + ((max_pixel_depth + 7) >> 3);
#ifdef PNG_MAX_MALLOC_64K
if (row_bytes > (png_uint_32)65536L)
@@ -4614,41 +4380,42 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
{
- png_free(png_ptr, png_ptr->big_row_buf);
- png_free(png_ptr, png_ptr->big_prev_row);
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->big_prev_row);
- if (png_ptr->interlaced != 0)
- png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
- row_bytes + 48);
+ if (png_ptr->interlaced)
+ png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+ row_bytes + 48);
- else
- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+ else
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
- png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
- /* Use 16-byte aligned memory for row_buf with at least 16 bytes
- * of padding before and after row_buf; treat prev_row similarly.
- * NOTE: the alignment is to the start of the pixels, one beyond the start
- * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
- * was incorrect; the filter byte was aligned, which had the exact
- * opposite effect of that intended.
- */
- {
- png_bytep temp = png_ptr->big_row_buf + 32;
- size_t extra = (size_t)temp & 0x0f;
- png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+ /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+ * of padding before and after row_buf; treat prev_row similarly.
+ * NOTE: the alignment is to the start of the pixels, one beyond the start
+ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
+ * was incorrect; the filter byte was aligned, which had the exact
+ * opposite effect of that intended.
+ */
+ {
+ png_bytep temp = png_ptr->big_row_buf + 32;
+ int extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+ temp = png_ptr->big_prev_row + 32;
+ extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+ }
- temp = png_ptr->big_prev_row + 32;
- extra = (size_t)temp & 0x0f;
- png_ptr->prev_row = temp - extra - 1/*filter byte*/;
- }
#else
- /* Use 31 bytes of padding before and 17 bytes after row_buf. */
- png_ptr->row_buf = png_ptr->big_row_buf + 31;
- png_ptr->prev_row = png_ptr->big_prev_row + 31;
+ /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+ png_ptr->row_buf = png_ptr->big_row_buf + 31;
+ png_ptr->prev_row = png_ptr->big_prev_row + 31;
#endif
- png_ptr->old_big_row_buf_size = row_bytes + 48;
+ png_ptr->old_big_row_buf_size = row_bytes + 48;
}
#ifdef PNG_MAX_MALLOC_64K
@@ -4673,7 +4440,7 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
* does not, so free the read buffer now regardless; the sequential reader
* reallocates it on demand.
*/
- if (png_ptr->read_buffer != NULL)
+ if (png_ptr->read_buffer)
{
png_bytep buffer = png_ptr->read_buffer;
@@ -4687,9 +4454,9 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
* IDAT stream has a bogus deflate header window_bits value, but this should
* not be happening any longer!)
*/
- if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
+ if (png_inflate_claim(png_ptr, png_IDAT, 0) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
png_ptr->flags |= PNG_FLAG_ROW_INIT;
}
-#endif /* READ */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngset.c b/Windows_Libs/Dev/Render/libpng/pngset.c
index 3e63c27..fcb0779 100644
--- a/Windows_Libs/Dev/Render/libpng/pngset.c
+++ b/Windows_Libs/Dev/Render/libpng/pngset.c
@@ -1,9 +1,10 @@
+
/* pngset.c - storage of image information into info struct
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -41,21 +42,27 @@ png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
png_fixed_point blue_x, png_fixed_point blue_y)
{
+ png_xy xy;
+
png_debug1(1, "in %s storage function", "cHRM fixed");
if (png_ptr == NULL || info_ptr == NULL)
return;
- info_ptr->cHRM.redx = red_x;
- info_ptr->cHRM.redy = red_y;
- info_ptr->cHRM.greenx = green_x;
- info_ptr->cHRM.greeny = green_y;
- info_ptr->cHRM.bluex = blue_x;
- info_ptr->cHRM.bluey = blue_y;
- info_ptr->cHRM.whitex = white_x;
- info_ptr->cHRM.whitey = white_y;
+ xy.redx = red_x;
+ xy.redy = red_y;
+ xy.greenx = green_x;
+ xy.greeny = green_y;
+ xy.bluex = blue_x;
+ xy.bluey = blue_y;
+ xy.whitex = white_x;
+ xy.whitey = white_y;
- info_ptr->valid |= PNG_INFO_cHRM;
+ if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
+ 2/* override with app values*/))
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
}
void PNGFAPI
@@ -67,7 +74,6 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
png_fixed_point int_blue_Z)
{
png_XYZ XYZ;
- png_xy xy;
png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
@@ -84,14 +90,10 @@ png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
XYZ.blue_Y = int_blue_Y;
XYZ.blue_Z = int_blue_Z;
- if (png_xy_from_XYZ(&xy, &XYZ) == 0)
- {
- info_ptr->cHRM = xy;
- info_ptr->valid |= PNG_INFO_cHRM;
- }
+ if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2))
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
- else
- png_app_error(png_ptr, "invalid cHRM XYZ");
+ png_colorspace_sync_info(png_ptr, info_ptr);
}
# ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -101,14 +103,14 @@ png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
double green_x, double green_y, double blue_x, double blue_y)
{
png_set_cHRM_fixed(png_ptr, info_ptr,
- png_fixed(png_ptr, white_x, "cHRM White X"),
- png_fixed(png_ptr, white_y, "cHRM White Y"),
- png_fixed(png_ptr, red_x, "cHRM Red X"),
- png_fixed(png_ptr, red_y, "cHRM Red Y"),
- png_fixed(png_ptr, green_x, "cHRM Green X"),
- png_fixed(png_ptr, green_y, "cHRM Green Y"),
- png_fixed(png_ptr, blue_x, "cHRM Blue X"),
- png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+ png_fixed(png_ptr, white_x, "cHRM White X"),
+ png_fixed(png_ptr, white_y, "cHRM White Y"),
+ png_fixed(png_ptr, red_x, "cHRM Red X"),
+ png_fixed(png_ptr, red_y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_x, "cHRM Green X"),
+ png_fixed(png_ptr, green_y, "cHRM Green Y"),
+ png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
}
void PNGAPI
@@ -117,243 +119,19 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
double blue_X, double blue_Y, double blue_Z)
{
png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
- png_fixed(png_ptr, red_X, "cHRM Red X"),
- png_fixed(png_ptr, red_Y, "cHRM Red Y"),
- png_fixed(png_ptr, red_Z, "cHRM Red Z"),
- png_fixed(png_ptr, green_X, "cHRM Green X"),
- png_fixed(png_ptr, green_Y, "cHRM Green Y"),
- png_fixed(png_ptr, green_Z, "cHRM Green Z"),
- png_fixed(png_ptr, blue_X, "cHRM Blue X"),
- png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
- png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
+ png_fixed(png_ptr, red_X, "cHRM Red X"),
+ png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, green_X, "cHRM Red X"),
+ png_fixed(png_ptr, green_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, blue_X, "cHRM Red X"),
+ png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
}
-# endif /* FLOATING_POINT */
+# endif /* PNG_FLOATING_POINT_SUPPORTED */
-#endif /* cHRM */
-
-#ifdef PNG_cICP_SUPPORTED
-void PNGAPI
-png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr,
- png_byte colour_primaries, png_byte transfer_function,
- png_byte matrix_coefficients, png_byte video_full_range_flag)
-{
- png_debug1(1, "in %s storage function", "cICP");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- info_ptr->cicp_colour_primaries = colour_primaries;
- info_ptr->cicp_transfer_function = transfer_function;
- info_ptr->cicp_matrix_coefficients = matrix_coefficients;
- info_ptr->cicp_video_full_range_flag = video_full_range_flag;
-
- if (info_ptr->cicp_matrix_coefficients != 0)
- {
- png_warning(png_ptr, "Invalid cICP matrix coefficients");
- return;
- }
-
- info_ptr->valid |= PNG_INFO_cICP;
-}
-#endif /* cICP */
-
-#ifdef PNG_cLLI_SUPPORTED
-void PNGFAPI
-png_set_cLLI_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
- /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
- * 100,000 as in the case of png_fixed_point.
- */
- png_uint_32 maxCLL, png_uint_32 maxFALL)
-{
- png_debug1(1, "in %s storage function", "cLLI");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* Check the light level range: */
- if (maxCLL > 0x7FFFFFFFU || maxFALL > 0x7FFFFFFFU)
- {
- /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
- * human vision is said to run up to 100Mcd/m2. The sun is about 2Gcd/m2.
- *
- * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
- * 2kcd/m2.
- */
- png_chunk_report(png_ptr, "cLLI light level exceeds PNG limit",
- PNG_CHUNK_WRITE_ERROR);
- return;
- }
-
- info_ptr->maxCLL = maxCLL;
- info_ptr->maxFALL = maxFALL;
- info_ptr->valid |= PNG_INFO_cLLI;
-}
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_cLLI(png_const_structrp png_ptr, png_inforp info_ptr,
- double maxCLL, double maxFALL)
-{
- png_set_cLLI_fixed(png_ptr, info_ptr,
- png_fixed_ITU(png_ptr, maxCLL, "png_set_cLLI(maxCLL)"),
- png_fixed_ITU(png_ptr, maxFALL, "png_set_cLLI(maxFALL)"));
-}
-# endif /* FLOATING_POINT */
-#endif /* cLLI */
-
-#ifdef PNG_mDCV_SUPPORTED
-static png_uint_16
-png_ITU_fixed_16(int *error, png_fixed_point v)
-{
- /* Return a safe uint16_t value scaled according to the ITU H273 rules for
- * 16-bit display chromaticities. Functions like the corresponding
- * png_fixed() internal function with regard to errors: it's an error on
- * write, a chunk_benign_error on read: See the definition of
- * png_chunk_report in pngpriv.h.
- */
- v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */
- if (v > 65535 || v < 0)
- {
- *error = 1;
- return 0;
- }
-
- return (png_uint_16)/*SAFE*/v;
-}
-
-void PNGAPI
-png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
- png_fixed_point white_x, png_fixed_point white_y,
- png_fixed_point red_x, png_fixed_point red_y,
- png_fixed_point green_x, png_fixed_point green_y,
- png_fixed_point blue_x, png_fixed_point blue_y,
- png_uint_32 maxDL,
- png_uint_32 minDL)
-{
- png_uint_16 rx, ry, gx, gy, bx, by, wx, wy;
- int error;
-
- png_debug1(1, "in %s storage function", "mDCV");
-
- if (png_ptr == NULL || info_ptr == NULL)
- return;
-
- /* Check the input values to ensure they are in the expected range: */
- error = 0;
- rx = png_ITU_fixed_16(&error, red_x);
- ry = png_ITU_fixed_16(&error, red_y);
- gx = png_ITU_fixed_16(&error, green_x);
- gy = png_ITU_fixed_16(&error, green_y);
- bx = png_ITU_fixed_16(&error, blue_x);
- by = png_ITU_fixed_16(&error, blue_y);
- wx = png_ITU_fixed_16(&error, white_x);
- wy = png_ITU_fixed_16(&error, white_y);
-
- if (error)
- {
- png_chunk_report(png_ptr,
- "mDCV chromaticities outside representable range",
- PNG_CHUNK_WRITE_ERROR);
- return;
- }
-
- /* Check the light level range: */
- if (maxDL > 0x7FFFFFFFU || minDL > 0x7FFFFFFFU)
- {
- /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
- * human vision is said to run up to 100Mcd/m2. The sun is about 2Gcd/m2.
- *
- * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
- * 2kcd/m2.
- */
- png_chunk_report(png_ptr, "mDCV display light level exceeds PNG limit",
- PNG_CHUNK_WRITE_ERROR);
- return;
- }
-
- /* All values are safe, the settings are accepted.
- *
- * IMPLEMENTATION NOTE: in practice the values can be checked and assigned
- * but the result is confusing if a writing app calls png_set_mDCV more than
- * once, the second time with an invalid value. This approach is more
- * obviously correct at the cost of typing and a very slight machine
- * overhead.
- */
- info_ptr->mastering_red_x = rx;
- info_ptr->mastering_red_y = ry;
- info_ptr->mastering_green_x = gx;
- info_ptr->mastering_green_y = gy;
- info_ptr->mastering_blue_x = bx;
- info_ptr->mastering_blue_y = by;
- info_ptr->mastering_white_x = wx;
- info_ptr->mastering_white_y = wy;
- info_ptr->mastering_maxDL = maxDL;
- info_ptr->mastering_minDL = minDL;
- info_ptr->valid |= PNG_INFO_mDCV;
-}
-
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-void PNGAPI
-png_set_mDCV(png_const_structrp png_ptr, png_inforp info_ptr,
- double white_x, double white_y, double red_x, double red_y, double green_x,
- double green_y, double blue_x, double blue_y,
- double maxDL, double minDL)
-{
- png_set_mDCV_fixed(png_ptr, info_ptr,
- png_fixed(png_ptr, white_x, "png_set_mDCV(white(x))"),
- png_fixed(png_ptr, white_y, "png_set_mDCV(white(y))"),
- png_fixed(png_ptr, red_x, "png_set_mDCV(red(x))"),
- png_fixed(png_ptr, red_y, "png_set_mDCV(red(y))"),
- png_fixed(png_ptr, green_x, "png_set_mDCV(green(x))"),
- png_fixed(png_ptr, green_y, "png_set_mDCV(green(y))"),
- png_fixed(png_ptr, blue_x, "png_set_mDCV(blue(x))"),
- png_fixed(png_ptr, blue_y, "png_set_mDCV(blue(y))"),
- png_fixed_ITU(png_ptr, maxDL, "png_set_mDCV(maxDL)"),
- png_fixed_ITU(png_ptr, minDL, "png_set_mDCV(minDL)"));
-}
-# endif /* FLOATING_POINT */
-#endif /* mDCV */
-
-#ifdef PNG_eXIf_SUPPORTED
-void PNGAPI
-png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
- png_bytep exif)
-{
- png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
- PNG_UNUSED(info_ptr)
- PNG_UNUSED(exif)
-}
-
-void PNGAPI
-png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
- png_uint_32 num_exif, png_bytep exif)
-{
- png_bytep new_exif;
-
- png_debug1(1, "in %s storage function", "eXIf");
-
- if (png_ptr == NULL || info_ptr == NULL ||
- (png_ptr->mode & PNG_WROTE_eXIf) != 0)
- return;
-
- new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif));
-
- if (new_exif == NULL)
- {
- png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
- return;
- }
-
- memcpy(new_exif, exif, (size_t)num_exif);
-
- png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0);
-
- info_ptr->num_exif = num_exif;
- info_ptr->exif = new_exif;
- info_ptr->free_me |= PNG_FREE_EXIF;
- info_ptr->valid |= PNG_INFO_eXIf;
-}
-#endif /* eXIf */
+#endif /* PNG_cHRM_SUPPORTED */
#ifdef PNG_gAMA_SUPPORTED
void PNGFAPI
@@ -365,8 +143,8 @@ png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL)
return;
- info_ptr->gamma = file_gamma;
- info_ptr->valid |= PNG_INFO_gAMA;
+ png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
+ png_colorspace_sync_info(png_ptr, info_ptr);
}
# ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -414,10 +192,11 @@ png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
return;
}
+ info_ptr->free_me |= PNG_FREE_HIST;
+
for (i = 0; i < info_ptr->num_palette; i++)
info_ptr->hist[i] = hist[i];
- info_ptr->free_me |= PNG_FREE_HIST;
info_ptr->valid |= PNG_INFO_hIST;
}
#endif
@@ -448,18 +227,27 @@ png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
info_ptr->channels = 1;
- else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
info_ptr->channels = 3;
else
info_ptr->channels = 1;
- if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
info_ptr->channels++;
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
- info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+ /* Check for potential overflow */
+ if (width >
+ (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */
+ - 48 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ info_ptr->rowbytes = 0;
+ else
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
}
#ifdef PNG_oFFs_SUPPORTED
@@ -485,13 +273,13 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
int nparams, png_const_charp units, png_charpp params)
{
- size_t length;
+ png_size_t length;
int i;
png_debug1(1, "in %s storage function", "pCAL");
if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
- || (nparams > 0 && params == NULL))
+ || (nparams > 0 && params == NULL))
return;
length = strlen(purpose) + 1;
@@ -502,45 +290,28 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
/* Check that the type matches the specification. */
if (type < 0 || type > 3)
- {
- png_chunk_report(png_ptr, "Invalid pCAL equation type",
- PNG_CHUNK_WRITE_ERROR);
- return;
- }
+ png_error(png_ptr, "Invalid pCAL equation type");
if (nparams < 0 || nparams > 255)
- {
- png_chunk_report(png_ptr, "Invalid pCAL parameter count",
- PNG_CHUNK_WRITE_ERROR);
- return;
- }
+ png_error(png_ptr, "Invalid pCAL parameter count");
/* Validate params[nparams] */
for (i=0; ipcal_purpose = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, length));
+ png_malloc_warn(png_ptr, length));
if (info_ptr->pcal_purpose == NULL)
{
- png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
- PNG_CHUNK_WRITE_ERROR);
+ png_warning(png_ptr, "Insufficient memory for pCAL purpose");
return;
}
memcpy(info_ptr->pcal_purpose, purpose, length);
- info_ptr->free_me |= PNG_FREE_PCAL;
-
png_debug(3, "storing X0, X1, type, and nparams in info");
info_ptr->pcal_X0 = X0;
info_ptr->pcal_X1 = X1;
@@ -549,10 +320,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
length = strlen(units) + 1;
png_debug1(3, "allocating units for info (%lu bytes)",
- (unsigned long)length);
+ (unsigned long)length);
info_ptr->pcal_units = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, length));
+ png_malloc_warn(png_ptr, length));
if (info_ptr->pcal_units == NULL)
{
@@ -563,7 +334,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(info_ptr->pcal_units, units, length);
info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
- (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
+ (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
if (info_ptr->pcal_params == NULL)
{
@@ -571,8 +342,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
return;
}
- memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
- (sizeof (png_charp)));
+ memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
for (i = 0; i < nparams; i++)
{
@@ -592,6 +362,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
}
info_ptr->valid |= PNG_INFO_pCAL;
+ info_ptr->free_me |= PNG_FREE_PCAL;
}
#endif
@@ -600,7 +371,7 @@ void PNGAPI
png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
int unit, png_const_charp swidth, png_const_charp sheight)
{
- size_t lengthw = 0, lengthh = 0;
+ png_size_t lengthw = 0, lengthh = 0;
png_debug1(1, "in %s storage function", "sCAL");
@@ -628,12 +399,11 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
info_ptr->scal_s_width = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, lengthw));
+ png_malloc_warn(png_ptr, lengthw));
if (info_ptr->scal_s_width == NULL)
{
png_warning(png_ptr, "Memory allocation failed while processing sCAL");
-
return;
}
@@ -644,11 +414,11 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
info_ptr->scal_s_height = png_voidcast(png_charp,
- png_malloc_warn(png_ptr, lengthh));
+ png_malloc_warn(png_ptr, lengthh));
if (info_ptr->scal_s_height == NULL)
{
- png_free(png_ptr, info_ptr->scal_s_width);
+ png_free (png_ptr, info_ptr->scal_s_width);
info_ptr->scal_s_width = NULL;
png_warning(png_ptr, "Memory allocation failed while processing sCAL");
@@ -657,8 +427,8 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(info_ptr->scal_s_height, sheight, lengthh);
- info_ptr->free_me |= PNG_FREE_SCAL;
info_ptr->valid |= PNG_INFO_sCAL;
+ info_ptr->free_me |= PNG_FREE_SCAL;
}
# ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -682,9 +452,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
char sheight[PNG_sCAL_MAX_DIGITS+1];
png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
- PNG_sCAL_PRECISION);
+ PNG_sCAL_PRECISION);
png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
- PNG_sCAL_PRECISION);
+ PNG_sCAL_PRECISION);
png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
}
@@ -742,17 +512,12 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_const_colorp palette, int num_palette)
{
- png_uint_32 max_palette_length;
-
png_debug1(1, "in %s storage function", "PLTE");
if (png_ptr == NULL || info_ptr == NULL)
return;
- max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
- (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
-
- if (num_palette < 0 || num_palette > (int) max_palette_length)
+ if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
{
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Invalid palette length");
@@ -760,7 +525,6 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
else
{
png_warning(png_ptr, "Invalid palette length");
-
return;
}
}
@@ -772,7 +536,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
# endif
))
{
- png_error(png_ptr, "Invalid palette");
+ png_chunk_report(png_ptr, "Invalid palette", PNG_CHUNK_ERROR);
+ return;
}
/* It may not actually be necessary to set png_ptr->palette here;
@@ -785,19 +550,19 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
/* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
- * of num_palette entries, in case of an invalid PNG file or incorrect
- * call to png_set_PLTE() with too-large sample values.
+ * of num_palette entries, in case of an invalid PNG file that has
+ * too-large sample values.
*/
png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
if (num_palette > 0)
- memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
- (sizeof (png_color)));
-
+ memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
info_ptr->palette = png_ptr->palette;
info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
info_ptr->free_me |= PNG_FREE_PLTE;
+
info_ptr->valid |= PNG_INFO_PLTE;
}
@@ -825,8 +590,8 @@ png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
if (png_ptr == NULL || info_ptr == NULL)
return;
- info_ptr->rendering_intent = srgb_intent;
- info_ptr->valid |= PNG_INFO_sRGB;
+ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
+ png_colorspace_sync_info(png_ptr, info_ptr);
}
void PNGAPI
@@ -838,20 +603,14 @@ png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL)
return;
- png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+ if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent))
+ {
+ /* This causes the gAMA and cHRM to be written too */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
-# ifdef PNG_gAMA_SUPPORTED
- png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
-# endif /* gAMA */
-
-# ifdef PNG_cHRM_SUPPORTED
- png_set_cHRM_fixed(png_ptr, info_ptr,
- /* color x y */
- /* white */ 31270, 32900,
- /* red */ 64000, 33000,
- /* green */ 30000, 60000,
- /* blue */ 15000, 6000);
-# endif /* cHRM */
+ png_colorspace_sync_info(png_ptr, info_ptr);
}
#endif /* sRGB */
@@ -864,7 +623,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_charp new_iccp_name;
png_bytep new_iccp_profile;
- size_t length;
+ png_size_t length;
png_debug1(1, "in %s storage function", "iCCP");
@@ -874,26 +633,45 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
png_app_error(png_ptr, "Invalid iCCP compression method");
+ /* Set the colorspace first because this validates the profile; do not
+ * override previously set app cHRM or gAMA here (because likely as not the
+ * application knows better than libpng what the correct values are.) Pass
+ * the info_ptr color_type field to png_colorspace_set_ICC because in the
+ * write case it has not yet been stored in png_ptr.
+ */
+ {
+ int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
+ proflen, profile, info_ptr->color_type);
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+
+ /* Don't do any of the copying if the profile was bad, or inconsistent. */
+ if (!result)
+ return;
+
+ /* But do write the gAMA and cHRM chunks from the profile. */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
+
length = strlen(name)+1;
new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
if (new_iccp_name == NULL)
{
png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
-
return;
}
memcpy(new_iccp_name, name, length);
new_iccp_profile = png_voidcast(png_bytep,
- png_malloc_warn(png_ptr, proflen));
+ png_malloc_warn(png_ptr, proflen));
if (new_iccp_profile == NULL)
{
png_free(png_ptr, new_iccp_name);
png_benign_error(png_ptr,
"Insufficient memory to process iCCP profile");
-
return;
}
@@ -917,7 +695,7 @@ png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
int ret;
ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
- if (ret != 0)
+ if (ret)
png_error(png_ptr, "Insufficient memory to store text");
}
@@ -927,11 +705,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
{
int i;
- png_debug1(1, "in text storage function, chunk typeid = 0x%lx",
- png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name);
+ png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
+ (unsigned long)png_ptr->chunk_name);
if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
- return 0;
+ return(0);
/* Make sure we have enough space in the "text" array in info_struct
* to hold all of the incoming text_ptr objects. This compare can't overflow
@@ -957,19 +735,18 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
else
max_text = INT_MAX;
- /* Now allocate a new array and copy the old members in; this does all
+ /* Now allocate a new array and copy the old members in, this does all
* the overflow checks.
*/
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
- info_ptr->text, old_num_text, max_text-old_num_text,
- sizeof *new_text));
+ info_ptr->text, old_num_text, max_text-old_num_text,
+ sizeof *new_text));
}
if (new_text == NULL)
{
png_chunk_report(png_ptr, "too many text chunks",
- PNG_CHUNK_WRITE_ERROR);
-
+ PNG_CHUNK_WRITE_ERROR);
return 1;
}
@@ -996,7 +773,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
{
png_chunk_report(png_ptr, "text compression mode is out of range",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
continue;
}
@@ -1025,10 +802,10 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
else
lang_key_len = 0;
}
-# else /* iTXt */
+# else /* PNG_iTXt_SUPPORTED */
{
png_chunk_report(png_ptr, "iTXt chunk not supported",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
continue;
}
# endif
@@ -1057,8 +834,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
if (textp->key == NULL)
{
png_chunk_report(png_ptr, "text chunk: out of memory",
- PNG_CHUNK_WRITE_ERROR);
-
+ PNG_CHUNK_WRITE_ERROR);
return 1;
}
@@ -1088,7 +864,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
textp->text = textp->key + key_len + 1;
}
- if (text_length != 0)
+ if (text_length)
memcpy(textp->text, text_ptr[i].text, text_length);
*(textp->text + text_length) = '\0';
@@ -1111,7 +887,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
}
- return 0;
+ return(0);
}
#endif
@@ -1123,7 +899,7 @@ png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(1, "in %s storage function", "tIME");
if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
- (png_ptr->mode & PNG_WROTE_tIME) != 0)
+ (png_ptr->mode & PNG_WROTE_tIME))
return;
if (mod_time->month == 0 || mod_time->month > 12 ||
@@ -1132,7 +908,6 @@ png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
mod_time->second > 60)
{
png_warning(png_ptr, "Ignoring invalid time value");
-
return;
}
@@ -1149,7 +924,6 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
png_debug1(1, "in %s storage function", "tRNS");
if (png_ptr == NULL || info_ptr == NULL)
-
return;
if (trans_alpha != NULL)
@@ -1165,36 +939,26 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
- if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
- {
- /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
- info_ptr->trans_alpha = png_voidcast(png_bytep,
- png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
- memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
- info_ptr->free_me |= PNG_FREE_TRNS;
- info_ptr->valid |= PNG_INFO_tRNS;
- }
- png_ptr->trans_alpha = info_ptr->trans_alpha;
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
}
if (trans_color != NULL)
{
-#ifdef PNG_WARNINGS_SUPPORTED
- if (info_ptr->bit_depth < 16)
- {
- int sample_max = (1 << info_ptr->bit_depth) - 1;
+ int sample_max = (1 << info_ptr->bit_depth);
- if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
- trans_color->gray > sample_max) ||
- (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
- (trans_color->red > sample_max ||
- trans_color->green > sample_max ||
- trans_color->blue > sample_max)))
- png_warning(png_ptr,
- "tRNS chunk has out-of-range samples for bit_depth");
- }
-#endif
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+ trans_color->gray > sample_max) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ (trans_color->red > sample_max ||
+ trans_color->green > sample_max ||
+ trans_color->blue > sample_max)))
+ png_warning(png_ptr,
+ "tRNS chunk has out-of-range samples for bit_depth");
info_ptr->trans_color = *trans_color;
@@ -1206,8 +970,8 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
if (num_trans != 0)
{
- info_ptr->free_me |= PNG_FREE_TRNS;
info_ptr->valid |= PNG_INFO_tRNS;
+ info_ptr->free_me |= PNG_FREE_TRNS;
}
}
#endif
@@ -1227,8 +991,6 @@ png_set_sPLT(png_const_structrp png_ptr,
{
png_sPLT_tp np;
- png_debug1(1, "in %s storage function", "sPLT");
-
if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
return;
@@ -1236,8 +998,8 @@ png_set_sPLT(png_const_structrp png_ptr,
* overflows. Notice that the parameters are (int) and (size_t)
*/
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
- info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
- sizeof *np));
+ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+ sizeof *np));
if (np == NULL)
{
@@ -1247,7 +1009,6 @@ png_set_sPLT(png_const_structrp png_ptr,
}
png_free(png_ptr, info_ptr->splt_palettes);
-
info_ptr->splt_palettes = np;
info_ptr->free_me |= PNG_FREE_SPLT;
@@ -1255,7 +1016,7 @@ png_set_sPLT(png_const_structrp png_ptr,
do
{
- size_t length;
+ png_size_t length;
/* Skip invalid input entries */
if (entries->name == NULL || entries->entries == NULL)
@@ -1268,8 +1029,8 @@ png_set_sPLT(png_const_structrp png_ptr,
np->depth = entries->depth;
- /* In the event of out-of-memory just return - there's no point keeping
- * on trying to add sPLT chunks.
+ /* In the even of out-of-memory just return - there's no point keeping on
+ * trying to add sPLT chunks.
*/
length = strlen(entries->name) + 1;
np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
@@ -1280,8 +1041,8 @@ png_set_sPLT(png_const_structrp png_ptr,
memcpy(np->name, entries->name, length);
/* IMPORTANT: we have memory now that won't get freed if something else
- * goes wrong; this code must free it. png_malloc_array produces no
- * warnings; use a png_chunk_report (below) if there is an error.
+ * goes wrong, this code must free it. png_malloc_array produces no
+ * warnings, use a png_chunk_report (below) if there is an error.
*/
np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
entries->nentries, sizeof (png_sPLT_entry)));
@@ -1289,7 +1050,6 @@ png_set_sPLT(png_const_structrp png_ptr,
if (np->entries == NULL)
{
png_free(png_ptr, np->name);
- np->name = NULL;
break;
}
@@ -1298,7 +1058,7 @@ png_set_sPLT(png_const_structrp png_ptr,
* checked it when doing the allocation.
*/
memcpy(np->entries, entries->entries,
- (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
+ entries->nentries * sizeof (png_sPLT_entry));
/* Note that 'continue' skips the advance of the out pointer and out
* count, so an invalid entry is not added.
@@ -1306,14 +1066,13 @@ png_set_sPLT(png_const_structrp png_ptr,
info_ptr->valid |= PNG_INFO_sPLT;
++(info_ptr->splt_palettes_num);
++np;
- ++entries;
}
- while (--nentries);
+ while (++entries, --nentries);
if (nentries > 0)
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
}
-#endif /* sPLT */
+#endif /* PNG_sPLT_SUPPORTED */
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
static png_byte
@@ -1322,17 +1081,17 @@ check_location(png_const_structrp png_ptr, int location)
location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
/* New in 1.6.0; copy the location and check it. This is an API
- * change; previously the app had to use the
+ * change, previously the app had to use the
* png_set_unknown_chunk_location API below for each chunk.
*/
- if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT))
{
/* Write struct, so unknown chunks come from the app */
png_app_warning(png_ptr,
- "png_set_unknown_chunks now expects a valid location");
+ "png_set_unknown_chunks now expects a valid location");
/* Use the old behavior */
location = (png_byte)(png_ptr->mode &
- (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
}
/* This need not be an internal error - if the app calls
@@ -1355,12 +1114,12 @@ check_location(png_const_structrp png_ptr, int location)
void PNGAPI
png_set_unknown_chunks(png_const_structrp png_ptr,
- png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
{
png_unknown_chunkp np;
if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
- unknowns == NULL)
+ unknowns == NULL)
return;
/* Check for the failure cases where support has been disabled at compile
@@ -1371,19 +1130,17 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
*/
# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
defined(PNG_READ_SUPPORTED)
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
{
png_app_error(png_ptr, "no unknown chunk support on read");
-
return;
}
# endif
# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
defined(PNG_WRITE_SUPPORTED)
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
{
png_app_error(png_ptr, "no unknown chunk support on write");
-
return;
}
# endif
@@ -1394,18 +1151,17 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
* appropriate to read or write.
*/
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
- info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
- sizeof *np));
+ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+ sizeof *np));
if (np == NULL)
{
png_chunk_report(png_ptr, "too many unknown chunks",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
return;
}
png_free(png_ptr, info_ptr->unknown_chunks);
-
info_ptr->unknown_chunks = np; /* safe because it is initialized */
info_ptr->free_me |= PNG_FREE_UNKN;
@@ -1429,12 +1185,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
else
{
np->data = png_voidcast(png_bytep,
- png_malloc_base(png_ptr, unknowns->size));
+ png_malloc_base(png_ptr, unknowns->size));
if (np->data == NULL)
{
png_chunk_report(png_ptr, "unknown chunk: out of memory",
- PNG_CHUNK_WRITE_ERROR);
+ PNG_CHUNK_WRITE_ERROR);
/* But just skip storing the unknown chunk */
continue;
}
@@ -1468,7 +1224,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_app_error(png_ptr, "invalid unknown chunk location");
/* Fake out the pre 1.6.0 behavior: */
- if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
+ if ((location & PNG_HAVE_IDAT)) /* undocumented! */
location = PNG_AFTER_IDAT;
else
@@ -1479,11 +1235,12 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
check_location(png_ptr, location);
}
}
-#endif /* STORE_UNKNOWN_CHUNKS */
+#endif
+
#ifdef PNG_MNG_FEATURES_SUPPORTED
png_uint_32 PNGAPI
-png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
+png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
{
png_debug(1, "in png_permit_mng_features");
@@ -1505,14 +1262,10 @@ add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
/* Utility function: update the 'keep' state of a chunk if it is already in
* the list, otherwise add it to the list.
*/
- for (i=0; i= PNG_HANDLE_CHUNK_LAST)
{
png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
-
return;
}
@@ -1556,17 +1308,13 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
/* Ignore all unknown chunks and all chunks recognized by
* libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
*/
- static const png_byte chunks_to_ignore[] = {
+ static PNG_CONST png_byte chunks_to_ignore[] = {
98, 75, 71, 68, '\0', /* bKGD */
99, 72, 82, 77, '\0', /* cHRM */
- 99, 73, 67, 80, '\0', /* cICP */
- 99, 76, 76, 73, '\0', /* cLLI */
- 101, 88, 73, 102, '\0', /* eXIf */
103, 65, 77, 65, '\0', /* gAMA */
104, 73, 83, 84, '\0', /* hIST */
105, 67, 67, 80, '\0', /* iCCP */
105, 84, 88, 116, '\0', /* iTXt */
- 109, 68, 67, 86, '\0', /* mDCV */
111, 70, 70, 115, '\0', /* oFFs */
112, 67, 65, 76, '\0', /* pCAL */
112, 72, 89, 115, '\0', /* pHYs */
@@ -1581,7 +1329,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
};
chunk_list = chunks_to_ignore;
- num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
+ num_chunks = (sizeof chunks_to_ignore)/5;
}
else /* num_chunks_in > 0 */
@@ -1592,11 +1340,10 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
* which can be switched off.
*/
png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
-
return;
}
- num_chunks = (unsigned int)num_chunks_in;
+ num_chunks = num_chunks_in;
}
old_num_chunks = png_ptr->num_chunk_list;
@@ -1608,7 +1355,6 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
if (num_chunks + old_num_chunks > UINT_MAX/5)
{
png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
-
return;
}
@@ -1616,7 +1362,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
* required because add_one_chunk above doesn't extend the list if the 'keep'
* parameter is the default.
*/
- if (keep != 0)
+ if (keep)
{
new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
5 * (num_chunks + old_num_chunks)));
@@ -1643,15 +1389,12 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
unsigned int i;
for (i=0; irow_pointers != NULL &&
- (info_ptr->row_pointers != row_pointers))
+ if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
info_ptr->row_pointers = row_pointers;
- if (row_pointers != NULL)
+ if (row_pointers)
info_ptr->valid |= PNG_INFO_IDAT;
}
#endif
void PNGAPI
-png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
+png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
{
- png_debug(1, "in png_set_compression_buffer_size");
+ if (png_ptr == NULL)
+ return;
- if (png_ptr == NULL)
- return;
-
- if (size == 0 || size > PNG_UINT_31_MAX)
- png_error(png_ptr, "invalid compression buffer size");
+ if (size == 0 || size > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid compression buffer size");
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
- {
- png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
- return;
- }
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+ {
+ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+ return;
+ }
# endif
# ifdef PNG_WRITE_SUPPORTED
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
- {
- if (png_ptr->zowner != 0)
+ if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
{
- png_warning(png_ptr,
- "Compression buffer size cannot be changed because it is in use");
+ if (png_ptr->zowner != 0)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size cannot be changed because it is in use");
+ return;
+ }
- return;
+ if (size > ZLIB_IO_MAX)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size limited to system maximum");
+ size = ZLIB_IO_MAX; /* must fit */
+ }
+
+ else if (size < 6)
+ {
+ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+ * if this is permitted.
+ */
+ png_warning(png_ptr,
+ "Compression buffer size cannot be reduced below 6");
+ return;
+ }
+
+ if (png_ptr->zbuffer_size != size)
+ {
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_ptr->zbuffer_size = (uInt)size;
+ }
}
-
-#ifndef __COVERITY__
- /* Some compilers complain that this is always false. However, it
- * can be true when integer overflow happens.
- */
- if (size > ZLIB_IO_MAX)
- {
- png_warning(png_ptr,
- "Compression buffer size limited to system maximum");
- size = ZLIB_IO_MAX; /* must fit */
- }
-#endif
-
- if (size < 6)
- {
- /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
- * if this is permitted.
- */
- png_warning(png_ptr,
- "Compression buffer size cannot be reduced below 6");
-
- return;
- }
-
- if (png_ptr->zbuffer_size != size)
- {
- png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
- png_ptr->zbuffer_size = (uInt)size;
- }
- }
# endif
}
void PNGAPI
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
{
- if (png_ptr != NULL && info_ptr != NULL)
- info_ptr->valid &= (unsigned int)(~mask);
+ if (png_ptr && info_ptr)
+ info_ptr->valid &= ~mask;
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* This function was added to libpng 1.2.6 */
void PNGAPI
-png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
+png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
png_uint_32 user_height_max)
{
- png_debug(1, "in png_set_user_limits");
-
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
- * regardless of dimensions, set both limits to 0x7fffffff.
+ * regardless of dimensions, set both limits to 0x7ffffffL.
*/
if (png_ptr == NULL)
return;
@@ -1813,41 +1543,21 @@ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
/* This function was added to libpng 1.4.0 */
void PNGAPI
-png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
+png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
{
- png_debug(1, "in png_set_chunk_cache_max");
-
- if (png_ptr != NULL)
- png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+ if (png_ptr)
+ png_ptr->user_chunk_cache_max = user_chunk_cache_max;
}
/* This function was added to libpng 1.4.1 */
void PNGAPI
-png_set_chunk_malloc_max(png_structrp png_ptr,
+png_set_chunk_malloc_max (png_structrp png_ptr,
png_alloc_size_t user_chunk_malloc_max)
{
- png_debug(1, "in png_set_chunk_malloc_max");
-
- /* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in
- * png.c. This API supports '0' for unlimited, make sure the correct
- * (unlimited) value is set here to avoid a need to check for 0 everywhere
- * the parameter is used.
- */
- if (png_ptr != NULL)
- {
- if (user_chunk_malloc_max == 0U) /* unlimited */
- {
-# ifdef PNG_MAX_MALLOC_64K
- png_ptr->user_chunk_malloc_max = 65536U;
-# else
- png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX;
-# endif
- }
- else
- png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
- }
+ if (png_ptr)
+ png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
}
-#endif /* ?SET_USER_LIMITS */
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
@@ -1862,7 +1572,7 @@ png_set_benign_errors(png_structrp png_ptr, int allowed)
* is the default behavior if png_set_benign_errors() is not called).
*/
- if (allowed != 0)
+ if (allowed)
png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
@@ -1870,14 +1580,14 @@ png_set_benign_errors(png_structrp png_ptr, int allowed)
png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
}
-#endif /* BENIGN_ERRORS */
+#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Whether to report invalid palette index; added at libng-1.5.10.
* It is possible for an indexed (color-type==3) PNG file to contain
* pixels with invalid (out-of-range) indexes if the PLTE chunk has
* fewer entries than the image's bit-depth would allow. We recover
- * from this gracefully by filling any incomplete palette with zeros
+ * from this gracefully by filling any incomplete palette with zeroes
* (opaque black). By default, when this occurs libpng will issue
* a benign error. This API can be used to override that behavior.
*/
@@ -1893,94 +1603,4 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
png_ptr->num_palette_max = -1;
}
#endif
-
-#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
- defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
-/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
- * and if invalid, correct the keyword rather than discarding the entire
- * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
- * length, forbids leading or trailing whitespace, multiple internal spaces,
- * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
- *
- * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
- * trailing '\0'). If this routine returns 0 then there was no keyword, or a
- * valid one could not be generated, and the caller must png_error.
- */
-png_uint_32 /* PRIVATE */
-png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
-{
-#ifdef PNG_WARNINGS_SUPPORTED
- png_const_charp orig_key = key;
-#endif
- png_uint_32 key_len = 0;
- int bad_character = 0;
- int space = 1;
-
- png_debug(1, "in png_check_keyword");
-
- if (key == NULL)
- {
- *new_key = 0;
- return 0;
- }
-
- while (*key && key_len < 79)
- {
- png_byte ch = (png_byte)*key++;
-
- if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
- {
- *new_key++ = ch; ++key_len; space = 0;
- }
-
- else if (space == 0)
- {
- /* A space or an invalid character when one wasn't seen immediately
- * before; output just a space.
- */
- *new_key++ = 32; ++key_len; space = 1;
-
- /* If the character was not a space then it is invalid. */
- if (ch != 32)
- bad_character = ch;
- }
-
- else if (bad_character == 0)
- bad_character = ch; /* just skip it, record the first error */
- }
-
- if (key_len > 0 && space != 0) /* trailing space */
- {
- --key_len; --new_key;
- if (bad_character == 0)
- bad_character = 32;
- }
-
- /* Terminate the keyword */
- *new_key = 0;
-
- if (key_len == 0)
- return 0;
-
-#ifdef PNG_WARNINGS_SUPPORTED
- /* Try to only output one warning per keyword: */
- if (*key != 0) /* keyword too long */
- png_warning(png_ptr, "keyword truncated");
-
- else if (bad_character != 0)
- {
- PNG_WARNING_PARAMETERS(p)
-
- png_warning_parameter(p, 1, orig_key);
- png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
-
- png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
- }
-#else /* !WARNINGS */
- PNG_UNUSED(png_ptr)
-#endif /* !WARNINGS */
-
- return key_len;
-}
-#endif /* TEXT || pCAL || iCCP || sPLT */
-#endif /* READ || WRITE */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngstruct.h b/Windows_Libs/Dev/Render/libpng/pngstruct.h
index fe5fa04..d58c028 100644
--- a/Windows_Libs/Dev/Render/libpng/pngstruct.h
+++ b/Windows_Libs/Dev/Render/libpng/pngstruct.h
@@ -1,18 +1,22 @@
-/* pngstruct.h - internal structures for libpng
+
+/* pngstruct.h - header file for PNG reference library
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*/
-#ifndef PNGPRIV_H
-# error This file must not be included by applications; please include
-#endif
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application.
+ */
#ifndef PNGSTRUCT_H
#define PNGSTRUCT_H
@@ -44,7 +48,7 @@
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
* can handle at once. This type need be no larger than 16 bits (so maximum of
* 65535), this define allows us to discover how big it is, but limited by the
- * maximum for size_t. The value can be overridden in a library build
+ * maximuum for png_size_t. The value can be overriden in a library build
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
* lower value (e.g. 255 works). A lower value may help memory usage (slightly)
* and may even improve performance on some systems (and degrade it on others.)
@@ -67,7 +71,13 @@ typedef struct png_compression_buffer
/* Colorspace support; structures used in png_struct, png_info and in internal
* functions to hold and communicate information about the color space.
+ *
+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
+ * colorspace corrections, otherwise all the colorspace information can be
+ * skipped and the size of libpng can be reduced (significantly) by compiling
+ * out the colorspace support.
*/
+#ifdef PNG_COLORSPACE_SUPPORTED
/* The chromaticities of the red, green and blue colorants and the chromaticity
* of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
*/
@@ -88,36 +98,48 @@ typedef struct png_XYZ
png_fixed_point green_X, green_Y, green_Z;
png_fixed_point blue_X, blue_Y, blue_Z;
} png_XYZ;
+#endif /* COLORSPACE */
-/* Chunk index values as an enum, PNG_INDEX_unknown is also a count of the
- * number of chunks.
- */
-#define PNG_CHUNK(cHNK, i) PNG_INDEX_ ## cHNK = (i),
-typedef enum
-{
- PNG_KNOWN_CHUNKS
- PNG_INDEX_unknown
-} png_index;
-#undef PNG_CHUNK
-
-/* Chunk flag values. These are (png_uint_32 values) with exactly one bit set
- * and can be combined into a flag set with bitwise 'or'.
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+/* A colorspace is all the above plus, potentially, profile information,
+ * however at present libpng does not use the profile internally so it is only
+ * stored in the png_info struct (if iCCP is supported.) The rendering intent
+ * is retained here and is checked.
*
- * TODO: C23: convert these macros to C23 inlines (which are static).
+ * The file gamma encoding information is also stored here and gamma correction
+ * is done by libpng, whereas color correction must currently be done by the
+ * application.
*/
-#define png_chunk_flag_from_index(i) (0x80000000U >> (31 - (i)))
- /* The flag coresponding to the given png_index enum value. This is defined
- * for png_unknown as well (until it reaches the value 32) but this should
- * not be relied on.
- */
+typedef struct png_colorspace
+{
+#ifdef PNG_GAMMA_SUPPORTED
+ png_fixed_point gamma; /* File gamma */
+#endif
-#define png_file_has_chunk(png_ptr, i)\
- (((png_ptr)->chunks & png_chunk_flag_from_index(i)) != 0)
- /* The chunk has been recorded in png_struct */
+#ifdef PNG_COLORSPACE_SUPPORTED
+ png_xy end_points_xy; /* End points as chromaticities */
+ png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
+ png_uint_16 rendering_intent; /* Rendering intent of a profile */
+#endif
-#define png_file_add_chunk(pnt_ptr, i)\
- ((void)((png_ptr)->chunks |= png_chunk_flag_from_index(i)))
- /* Record the chunk in the png_struct */
+ /* Flags are always defined to simplify the code. */
+ png_uint_16 flags; /* As defined below */
+} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+
+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+
+/* General flags for the 'flags' field */
+#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
+#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
+#define PNG_COLORSPACE_HAVE_INTENT 0x0004
+#define PNG_COLORSPACE_FROM_gAMA 0x0008
+#define PNG_COLORSPACE_FROM_cHRM 0x0010
+#define PNG_COLORSPACE_FROM_sRGB 0x0020
+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
+#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */
+#define PNG_COLORSPACE_INVALID 0x8000
+#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags))
+#endif /* COLORSPACE || GAMMA */
struct png_struct_def
{
@@ -189,34 +211,27 @@ struct png_struct_def
int zlib_set_strategy;
#endif
- png_uint_32 chunks; /* PNG_CF_ for every chunk read or (NYI) written */
-# define png_has_chunk(png_ptr, cHNK)\
- png_file_has_chunk(png_ptr, PNG_INDEX_ ## cHNK)
- /* Convenience accessor - use this to check for a known chunk by name */
-
png_uint_32 width; /* width of image in pixels */
png_uint_32 height; /* height of image in pixels */
png_uint_32 num_rows; /* number of rows in current pass */
png_uint_32 usr_width; /* width of row at start of write */
- size_t rowbytes; /* size of row in bytes */
+ png_size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */
png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
png_bytep prev_row; /* buffer to save previous (unfiltered) row.
- * While reading this is a pointer into
- * big_prev_row; while writing it is separately
- * allocated if needed.
+ * This is a pointer into big_prev_row
*/
png_bytep row_buf; /* buffer to save current (unfiltered) row.
- * While reading, this is a pointer into
- * big_row_buf; while writing it is separately
- * allocated.
+ * This is a pointer into big_row_buf
*/
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- png_bytep try_row; /* buffer to save trial row when filtering */
- png_bytep tst_row; /* buffer to save best trial row when filtering */
+#ifdef PNG_WRITE_SUPPORTED
+ png_bytep sub_row; /* buffer to save "sub" row when filtering */
+ png_bytep up_row; /* buffer to save "up" row when filtering */
+ png_bytep avg_row; /* buffer to save "avg" row when filtering */
+ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
#endif
- size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
+ png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
png_uint_32 idat_size; /* current IDAT size for read */
png_uint_32 crc; /* current chunk CRC value */
@@ -233,7 +248,7 @@ struct png_struct_def
png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */
- png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row: write only */
@@ -247,9 +262,6 @@ struct png_struct_def
/* pixel depth used for the row buffers */
png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */
-#if ZLIB_VERNUM >= 0x1240
- png_byte zstream_start; /* at start of an input zlib stream */
-#endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */
#endif
@@ -262,7 +274,7 @@ struct png_struct_def
#ifdef PNG_READ_GAMMA_SUPPORTED
png_color_16 background_1; /* background normalized to gamma 1.0 */
#endif
-#endif /* bKGD */
+#endif /* PNG_bKGD_SUPPORTED */
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_flush_ptr output_flush_fn; /* Function for flushing output */
@@ -270,16 +282,9 @@ struct png_struct_def
png_uint_32 flush_rows; /* number of rows written since last flush */
#endif
-#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
- png_xy chromaticities; /* From mDVC, cICP, [iCCP], sRGB or cHRM */
-#endif
-
#ifdef PNG_READ_GAMMA_SUPPORTED
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
- png_fixed_point screen_gamma; /* screen gamma value (display exponent) */
- png_fixed_point file_gamma; /* file gamma value (encoding exponent) */
- png_fixed_point chunk_gamma; /* from cICP, iCCP, sRGB or gAMA */
- png_fixed_point default_gamma;/* from png_set_alpha_mode */
+ png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
png_bytep gamma_table; /* gamma table for 8-bit depth files */
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
@@ -291,14 +296,14 @@ struct png_struct_def
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
-#endif /* READ_GAMMA */
+#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
png_color_8 sig_bit; /* significant bits in each available channel */
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
- png_color_8 shift; /* shift for significant bit transformation */
+ png_color_8 shift; /* shift for significant bit tranformation */
#endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
@@ -319,30 +324,50 @@ struct png_struct_def
png_bytep current_buffer; /* buffer for recently used data */
png_uint_32 push_length; /* size of current input chunk */
png_uint_32 skip_length; /* bytes to skip in input data */
- size_t save_buffer_size; /* amount of data now in save_buffer */
- size_t save_buffer_max; /* total size of save_buffer */
- size_t buffer_size; /* total amount of available input data */
- size_t current_buffer_size; /* amount of data now in current_buffer */
+ png_size_t save_buffer_size; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max; /* total size of save_buffer */
+ png_size_t buffer_size; /* total amount of available input data */
+ png_size_t current_buffer_size; /* amount of data now in current_buffer */
int process_mode; /* what push library is currently doing */
int cur_palette; /* current push library palette index */
-#endif /* PROGRESSIVE_READ */
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* For the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr;
+ png_bytep offset_table;
+ png_uint_16 offset_table_number;
+ png_uint_16 offset_table_count;
+ png_uint_16 offset_table_count_free;
+#endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED
png_bytep palette_lookup; /* lookup table for quantizing */
png_bytep quantize_index; /* index translation for palette files */
#endif
-/* Options */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_byte heuristic_method; /* heuristic for row filter selection */
+ png_byte num_prev_filters; /* number of weights for previous rows */
+ png_bytep prev_filters; /* filter type(s) of previous row(s) */
+ png_uint_16p filter_weights; /* weight(s) for previous line(s) */
+ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
+ png_uint_16p filter_costs; /* relative filter calculation cost */
+ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
+#endif
+
+ /* Options */
#ifdef PNG_SET_OPTION_SUPPORTED
- png_uint_32 options; /* On/off state (up to 16 options) */
+ png_byte options; /* On/off state (up to 4 options) */
#endif
#if PNG_LIBPNG_VER < 10700
/* To do: remove this from libpng-1.7 */
#ifdef PNG_TIME_RFC1123_SUPPORTED
char time_buffer[29]; /* String to hold RFC 1123 time text */
-#endif /* TIME_RFC1123 */
-#endif /* LIBPNG_VER < 10700 */
+#endif
+#endif
/* New members added in libpng-1.0.6 */
@@ -352,8 +377,8 @@ struct png_struct_def
png_voidp user_chunk_ptr;
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
-#endif /* READ_USER_CHUNKS */
-#endif /* USER_CHUNKS */
+#endif
+#endif
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
int unknown_default; /* As PNG_HANDLE_* */
@@ -373,13 +398,6 @@ struct png_struct_def
/* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
#endif
-/* New member added in libpng-1.6.36 */
-#if defined(PNG_READ_EXPAND_SUPPORTED) && \
- (defined(PNG_ARM_NEON_IMPLEMENTATION) || \
- defined(PNG_RISCV_RVV_IMPLEMENTATION))
- png_bytep riffled_palette; /* buffer for accelerated palette expansion */
-#endif
-
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
#if defined(PNG_MNG_FEATURES_SUPPORTED)
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
@@ -405,6 +423,7 @@ struct png_struct_def
#ifdef PNG_READ_QUANTIZE_SUPPORTED
/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep quantize_sort; /* working sort array */
png_bytep index_to_palette; /* where the original index currently is
in the palette */
png_bytep palette_to_index; /* which original index points to this
@@ -438,7 +457,7 @@ struct png_struct_def
#endif
/* New member added in libpng-1.2.26 */
- size_t old_big_row_buf_size;
+ png_size_t old_big_row_buf_size;
#ifdef PNG_READ_SUPPORTED
/* New member added in libpng-1.2.30 */
@@ -460,5 +479,11 @@ struct png_struct_def
/* New member added in libpng-1.5.7 */
void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row);
+
+#ifdef PNG_READ_SUPPORTED
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ png_colorspace colorspace;
+#endif
+#endif
};
#endif /* PNGSTRUCT_H */
diff --git a/Windows_Libs/Dev/Render/libpng/pngtest.c b/Windows_Libs/Dev/Render/libpng/pngtest.c
index 5426b83..144f2db 100644
--- a/Windows_Libs/Dev/Render/libpng/pngtest.c
+++ b/Windows_Libs/Dev/Render/libpng/pngtest.c
@@ -1,9 +1,10 @@
-/* pngtest.c - a test program for libpng
+
+/* pngtest.c - a simple test program to test libpng
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -36,87 +37,57 @@
#include
#include
-#ifdef PNG_ZLIB_HEADER
-# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */
-#else
-# include
-#endif
+/* Defined so I can write to a file on gui/windowing platforms */
+/* #define STDERR stderr */
+#define STDERR stdout /* For DOS */
#include "png.h"
-/* This hack was introduced for historical reasons, and we are
- * still keeping it in libpng-1.6.x for compatibility reasons.
+/* Known chunks that exist in pngtest.png must be supported or pngtest will fail
+ * simply as a result of re-ordering them. This may be fixed in 1.7
*/
-#define STDERR stdout
-
-/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_55 Your_png_h_is_not_version_1_6_55;
-
-/* Ensure that all version numbers in png.h are consistent with one another. */
-#if (PNG_LIBPNG_VER != PNG_LIBPNG_VER_MAJOR * 10000 + \
- PNG_LIBPNG_VER_MINOR * 100 + \
- PNG_LIBPNG_VER_RELEASE) || \
- (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_MAJOR * 10 + \
- PNG_LIBPNG_VER_MINOR) || \
- (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_SONUM) || \
- (PNG_LIBPNG_VER_SHAREDLIB != PNG_LIBPNG_VER_DLLNUM)
-# error Inconsistent version numbers in "png.h"
-#endif
-
-/* In version 1.6.1, we added support for the configure test harness, which
- * uses 77 to indicate a skipped test. On the other hand, in cmake build tests,
- * we still need to succeed on a skipped test, so:
- */
-#if defined(HAVE_CONFIG_H)
-# define SKIP 77
-#else
-# define SKIP 0
-#endif
-
-/* Known chunks that exist in pngtest.png must be supported, or pngtest will
- * fail simply as a result of re-ordering them. This may be fixed in the next
- * generation of libpng.
- *
- * pngtest allocates a single row buffer for each row and overwrites it,
- * therefore if the write side doesn't support the writing of interlaced images
- * nothing can be done for an interlaced image (and the code below will fail
- * horribly trying to write extra data after writing garbage).
- */
-#if defined PNG_READ_SUPPORTED && /* else nothing can be done */ \
- defined PNG_READ_bKGD_SUPPORTED && \
- defined PNG_READ_cHRM_SUPPORTED && \
- defined PNG_READ_gAMA_SUPPORTED && \
- defined PNG_READ_oFFs_SUPPORTED && \
- defined PNG_READ_pCAL_SUPPORTED && \
- defined PNG_READ_pHYs_SUPPORTED && \
- defined PNG_READ_sBIT_SUPPORTED && \
- defined PNG_READ_sCAL_SUPPORTED && \
- defined PNG_READ_sRGB_SUPPORTED && \
- defined PNG_READ_sPLT_SUPPORTED && \
- defined PNG_READ_tEXt_SUPPORTED && \
- defined PNG_READ_tIME_SUPPORTED && \
- defined PNG_READ_zTXt_SUPPORTED && \
- (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700)
+#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\
+ defined PNG_READ_bKGD_SUPPORTED &&\
+ defined PNG_READ_cHRM_SUPPORTED &&\
+ defined PNG_READ_gAMA_SUPPORTED &&\
+ defined PNG_READ_oFFs_SUPPORTED &&\
+ defined PNG_READ_pCAL_SUPPORTED &&\
+ defined PNG_READ_pHYs_SUPPORTED &&\
+ defined PNG_READ_sBIT_SUPPORTED &&\
+ defined PNG_READ_sCAL_SUPPORTED &&\
+ defined PNG_READ_sRGB_SUPPORTED &&\
+ defined PNG_READ_tEXt_SUPPORTED &&\
+ defined PNG_READ_tIME_SUPPORTED &&\
+ defined PNG_READ_zTXt_SUPPORTED
+#include "zlib.h"
/* Copied from pngpriv.h but only used in error messages below. */
#ifndef PNG_ZBUF_SIZE
# define PNG_ZBUF_SIZE 8192
#endif
+#define FCLOSE(file) fclose(file)
+#ifndef PNG_STDIO_SUPPORTED
+typedef FILE * png_FILE_p;
+#endif
+
+/* Makes pngtest verbose so we can find problems. */
#ifndef PNG_DEBUG
# define PNG_DEBUG 0
#endif
#if PNG_DEBUG > 1
-# define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
-# define pngtest_debug1(m, p1) ((void)fprintf(stderr, m "\n", p1))
-# define pngtest_debug2(m, p1, p2) ((void)fprintf(stderr, m "\n", p1, p2))
-#elif PNG_DEBUG == 0 || PNG_DEBUG == 1
-# define pngtest_debug(m) ((void)0)
-# define pngtest_debug1(m, p1) ((void)0)
-# define pngtest_debug2(m, p1, p2) ((void)0)
-#else /* PNG_DEBUG < 0 */
-# error Bad PNG_DEBUG value
+# define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
+# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1))
+# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2))
+#else
+# define pngtest_debug(m) ((void)0)
+# define pngtest_debug1(m,p1) ((void)0)
+# define pngtest_debug2(m,p1,p2) ((void)0)
+#endif
+
+#if !PNG_DEBUG
+# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */
#endif
/* Turn on CPU timing
@@ -133,21 +104,38 @@ static float t_start, t_stop, t_decode, t_encode, t_misc;
#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
+#define PNG_tIME_STRING_LENGTH 29
static int tIME_chunk_present = 0;
-static char tIME_string[29] = "tIME chunk is not present";
-/* This use case is deprecated.
- * See the declaration of png_convert_to_rfc1123_buffer for more details.
- */
+static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
#endif
static int verbose = 0;
static int strict = 0;
static int relaxed = 0;
-static int xfail = 0;
static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
static int error_count = 0; /* count calls to png_error */
static int warning_count = 0; /* count calls to png_warning */
+#ifdef __TURBOC__
+#include
+#endif
+
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
+#endif
+
+/* Defines for unknown chunk handling if required. */
+#ifndef PNG_HANDLE_CHUNK_ALWAYS
+# define PNG_HANDLE_CHUNK_ALWAYS 3
+#endif
+#ifndef PNG_HANDLE_CHUNK_IF_SAFE
+# define PNG_HANDLE_CHUNK_IF_SAFE 2
+#endif
+
+/* Utility to save typing/errors, the argument must be a name */
+#define MEMZERO(var) ((void)memset(&var, 0, sizeof var))
+
/* Example of using row callbacks to make a simple progress meter */
static int status_pass = 1;
static int status_dots_requested = 0;
@@ -156,13 +144,8 @@ static int status_dots = 1;
static void PNGCBAPI
read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
{
- /* The callback should always receive correct parameters. */
- if (png_ptr == NULL)
- png_error(png_ptr, "read_row_callback: bad png_ptr");
- if (row_number > PNG_UINT_31_MAX)
- png_error(png_ptr, "read_row_callback: bad row number");
- if (pass < 0 || pass > 7)
- png_error(png_ptr, "read_row_callback: bad pass");
+ if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
+ return;
if (status_pass != pass)
{
@@ -176,7 +159,7 @@ read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
if (status_dots == 0)
{
fprintf(stdout, "\n ");
- status_dots = 30;
+ status_dots=30;
}
fprintf(stdout, "r");
@@ -186,13 +169,8 @@ read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
static void PNGCBAPI
write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
{
- /* The callback should always receive correct parameters. */
- if (png_ptr == NULL)
- png_error(png_ptr, "write_row_callback: bad png_ptr");
- if (row_number > PNG_UINT_31_MAX)
- png_error(png_ptr, "write_row_callback: bad row number");
- if (pass < 0 || pass > 7)
- png_error(png_ptr, "write_row_callback: bad pass");
+ if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
+ return;
fprintf(stdout, "w");
}
@@ -200,18 +178,16 @@ write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
-/* Example of using a user transform callback (doesn't do anything at present).
+/* Example of using user transform callback (we don't transform anything,
+ * but merely examine the row filters. We set this to 256 rather than
+ * 5 in case illegal filter values are present.)
*/
+static png_uint_32 filters_used[256];
static void PNGCBAPI
-read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
{
- /* The callback should always receive correct parameters. */
- if (png_ptr == NULL)
- png_error(png_ptr, "read_user_callback: bad png_ptr");
- if (row_info == NULL)
- png_error(png_ptr, "read_user_callback: bad row info");
- if (data == NULL)
- png_error(png_ptr, "read_user_callback: bad data");
+ if (png_ptr != NULL && row_info != NULL)
+ ++filters_used[*(data - 1)];
}
#endif
@@ -226,14 +202,8 @@ static void PNGCBAPI
count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
{
png_bytep dp = data;
-
- /* The callback should always receive correct parameters. */
if (png_ptr == NULL)
- png_error(png_ptr, "count_zero_samples: bad png_ptr");
- if (row_info == NULL)
- png_error(png_ptr, "count_zero_samples: bad row info");
- if (data == NULL)
- png_error(png_ptr, "count_zero_samples: bad data");
+ return;
/* Contents of row_info:
* png_uint_32 width width of row
@@ -244,97 +214,96 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
* png_byte pixel_depth bits per pixel (depth*channels)
*/
- /* Counts the number of zero samples (or zero pixels if color_type is 3 */
+ /* Counts the number of zero samples (or zero pixels if color_type is 3 */
- if (row_info->color_type == 0 || row_info->color_type == 3)
- {
- int pos = 0;
- png_uint_32 n, nstop;
+ if (row_info->color_type == 0 || row_info->color_type == 3)
+ {
+ int pos = 0;
+ png_uint_32 n, nstop;
- for (n = 0, nstop = row_info->width; n < nstop; n++)
- {
- if (row_info->bit_depth == 1)
- {
- if (((*dp << pos++ ) & 0x80) == 0)
- zero_samples++;
+ for (n = 0, nstop=row_info->width; nbit_depth == 1)
+ {
+ if (((*dp << pos++ ) & 0x80) == 0)
+ zero_samples++;
- if (pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
- if (row_info->bit_depth == 2)
- {
- if (((*dp << (pos+=2)) & 0xc0) == 0)
- zero_samples++;
+ if (row_info->bit_depth == 2)
+ {
+ if (((*dp << (pos+=2)) & 0xc0) == 0)
+ zero_samples++;
- if (pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
- if (row_info->bit_depth == 4)
- {
- if (((*dp << (pos+=4)) & 0xf0) == 0)
- zero_samples++;
+ if (row_info->bit_depth == 4)
+ {
+ if (((*dp << (pos+=4)) & 0xf0) == 0)
+ zero_samples++;
- if (pos == 8)
- {
- pos = 0;
- dp++;
- }
- }
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
- if (row_info->bit_depth == 8)
- if (*dp++ == 0)
- zero_samples++;
+ if (row_info->bit_depth == 8)
+ if (*dp++ == 0)
+ zero_samples++;
- if (row_info->bit_depth == 16)
- {
- if ((*dp | *(dp+1)) == 0)
- zero_samples++;
- dp += 2;
- }
- }
- }
- else /* Other color types */
- {
- png_uint_32 n, nstop;
- int channel;
- int color_channels = row_info->channels;
- if (row_info->color_type > 3)
- color_channels--;
+ if (row_info->bit_depth == 16)
+ {
+ if ((*dp | *(dp+1)) == 0)
+ zero_samples++;
+ dp+=2;
+ }
+ }
+ }
+ else /* Other color types */
+ {
+ png_uint_32 n, nstop;
+ int channel;
+ int color_channels = row_info->channels;
+ if (row_info->color_type > 3)color_channels--;
- for (n = 0, nstop = row_info->width; n < nstop; n++)
- {
- for (channel = 0; channel < color_channels; channel++)
- {
- if (row_info->bit_depth == 8)
- if (*dp++ == 0)
- zero_samples++;
+ for (n = 0, nstop=row_info->width; nbit_depth == 8)
+ if (*dp++ == 0)
+ zero_samples++;
- if (row_info->bit_depth == 16)
- {
- if ((*dp | *(dp+1)) == 0)
- zero_samples++;
+ if (row_info->bit_depth == 16)
+ {
+ if ((*dp | *(dp+1)) == 0)
+ zero_samples++;
- dp += 2;
- }
- }
- if (row_info->color_type > 3)
- {
- dp++;
- if (row_info->bit_depth == 16)
- dp++;
- }
- }
- }
+ dp+=2;
+ }
+ }
+ if (row_info->color_type > 3)
+ {
+ dp++;
+ if (row_info->bit_depth == 16)
+ dp++;
+ }
+ }
+ }
}
-#endif /* WRITE_USER_TRANSFORM */
+#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
#ifndef PNG_STDIO_SUPPORTED
/* START of code to validate stdio-free compilation */
@@ -348,8 +317,11 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
#ifdef PNG_IO_STATE_SUPPORTED
void
-pngtest_check_io_state(png_structp png_ptr, size_t data_length,
- png_uint_32 io_op)
+pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
+ png_uint_32 io_op);
+void
+pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
+ png_uint_32 io_op)
{
png_uint_32 io_state = png_get_io_state(png_ptr);
int err = 0;
@@ -361,7 +333,7 @@ pngtest_check_io_state(png_structp png_ptr, size_t data_length,
/* Check if the buffer size specific to the current location
* (file signature / header / data / crc) is as expected.
*/
- switch ((io_state & PNG_IO_MASK_LOC) != 0)
+ switch (io_state & PNG_IO_MASK_LOC)
{
case PNG_IO_SIGNATURE:
if (data_length > 8)
@@ -380,29 +352,30 @@ pngtest_check_io_state(png_structp png_ptr, size_t data_length,
default:
err = 1; /* uninitialized */
}
- if (err != 0)
+ if (err)
png_error(png_ptr, "Bad I/O state or buffer size");
}
#endif
static void PNGCBAPI
-pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length)
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
- size_t check = 0;
+ png_size_t check = 0;
png_voidp io_ptr;
- if (png_ptr == NULL)
- png_error(png_ptr, "pngtest_read_data: bad png_ptr");
-
- /* fread() returns 0 on error, so it is OK to store this in a size_t
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
io_ptr = png_get_io_ptr(png_ptr);
if (io_ptr != NULL)
- check = fread(data, 1, length, (FILE *)io_ptr);
+ {
+ check = fread(data, 1, length, (png_FILE_p)io_ptr);
+ }
if (check != length)
+ {
png_error(png_ptr, "Read Error");
+ }
#ifdef PNG_IO_STATE_SUPPORTED
pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
@@ -413,10 +386,8 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length)
static void PNGCBAPI
pngtest_flush(png_structp png_ptr)
{
- if (png_ptr == NULL)
- png_error(png_ptr, "pngtest_flush: bad png_ptr");
-
/* Do nothing; fflush() is said to be just a waste of energy. */
+ PNG_UNUSED(png_ptr) /* Stifle compiler warning */
}
#endif
@@ -426,23 +397,22 @@ pngtest_flush(png_structp png_ptr)
* than changing the library.
*/
static void PNGCBAPI
-pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length)
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
- size_t check;
+ png_size_t check;
- if (png_ptr == NULL)
- png_error(png_ptr, "pngtest_write_data: bad png_ptr");
-
- check = fwrite(data, 1, length, (FILE *)png_get_io_ptr(png_ptr));
+ check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
if (check != length)
+ {
png_error(png_ptr, "Write Error");
+ }
#ifdef PNG_IO_STATE_SUPPORTED
pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
#endif
}
-#endif /* !STDIO */
+#endif /* !PNG_STDIO_SUPPORTED */
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
@@ -451,13 +421,13 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length)
*/
typedef struct
{
- const char *file_name;
+ PNG_CONST char *file_name;
} pngtest_error_parameters;
static void PNGCBAPI
pngtest_warning(png_structp png_ptr, png_const_charp message)
{
- const char *name = "UNKNOWN (ERROR!)";
+ PNG_CONST char *name = "UNKNOWN (ERROR!)";
pngtest_error_parameters *test =
(pngtest_error_parameters*)png_get_error_ptr(png_ptr);
@@ -466,7 +436,7 @@ pngtest_warning(png_structp png_ptr, png_const_charp message)
if (test != NULL && test->file_name != NULL)
name = test->file_name;
- fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message);
+ fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
}
/* This is the default error handling function. Note that replacements for
@@ -491,7 +461,7 @@ pngtest_error(png_structp png_ptr, png_const_charp message)
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
/* Allocate memory. For reasonable files, size should never exceed
- * 64K. However, zlib may allocate more than 64K if you don't tell
+ * 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
@@ -501,8 +471,8 @@ pngtest_error(png_structp png_ptr, png_const_charp message)
*/
typedef struct memory_information
{
- png_alloc_size_t size;
- png_voidp pointer;
+ png_alloc_size_t size;
+ png_voidp pointer;
struct memory_information *next;
} memory_information;
typedef memory_information *memory_infop;
@@ -513,9 +483,9 @@ static int maximum_allocation = 0;
static int total_allocation = 0;
static int num_allocations = 0;
-png_voidp PNGCBAPI png_debug_malloc(png_structp png_ptr,
- png_alloc_size_t size);
-void PNGCBAPI png_debug_free(png_structp png_ptr, png_voidp ptr);
+png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,
+ png_alloc_size_t size));
+void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
png_voidp
PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
@@ -526,7 +496,7 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
*/
if (size == 0)
- return NULL;
+ return (NULL);
/* This calls the library allocator twice, once to get the requested
buffer and once to get a new free list entry. */
@@ -535,11 +505,11 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
memory_infop pinfo;
png_set_mem_fn(png_ptr, NULL, NULL, NULL);
pinfo = (memory_infop)png_malloc(png_ptr,
- (sizeof *pinfo));
+ (sizeof *pinfo));
pinfo->size = size;
current_allocation += size;
total_allocation += size;
- ++num_allocations;
+ num_allocations ++;
if (current_allocation > maximum_allocation)
maximum_allocation = current_allocation;
@@ -563,11 +533,11 @@ PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
/* Make sure the caller isn't assuming zeroed memory. */
memset(pinfo->pointer, 0xdd, pinfo->size);
- if (verbose != 0)
+ if (verbose)
printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
- pinfo->pointer);
+ pinfo->pointer);
- return (png_voidp)pinfo->pointer;
+ return (png_voidp)(pinfo->pointer);
}
}
@@ -587,7 +557,6 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
}
/* Unlink the element from the list. */
- if (pinformation != NULL)
{
memory_infop *ppinfo = &pinformation;
@@ -604,14 +573,14 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
/* We must free the list element too, but first kill
the memory that is to be freed. */
memset(ptr, 0x55, pinfo->size);
- free(pinfo);
+ png_free_default(png_ptr, pinfo);
pinfo = NULL;
break;
}
if (pinfo->next == NULL)
{
- fprintf(STDERR, "Pointer %p not found\n", ptr);
+ fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
break;
}
@@ -620,14 +589,13 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
}
/* Finally free the data. */
- if (verbose != 0)
+ if (verbose)
printf("Freeing %p\n", ptr);
- if (ptr != NULL)
- free(ptr);
+ png_free_default(png_ptr, ptr);
ptr = NULL;
}
-#endif /* USER_MEM && DEBUG */
+#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
/* END of code to test memory allocation/deallocation */
@@ -637,14 +605,15 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
/* (sTER is a public chunk not yet known by libpng. vpAg is a private
chunk used in ImageMagick to store "virtual page" size). */
-typedef struct user_chunk_info_def
+static struct user_chunk_data
{
png_const_infop info_ptr;
- png_uint_32 vpAg_width, vpAg_height;
- png_byte vpAg_units;
- png_byte sTER_mode;
- int location[2];
-} user_chunk_info;
+ png_uint_32 vpAg_width, vpAg_height;
+ png_byte vpAg_units;
+ png_byte sTER_mode;
+ int location[2];
+}
+user_chunk_data;
/* Used for location and order; zero means nothing. */
#define have_sTER 0x01
@@ -654,60 +623,59 @@ typedef struct user_chunk_info_def
#define after_IDAT 0x40
static void
-init_user_chunk_info(png_const_infop info_ptr, user_chunk_info *chunk_data)
+init_callback_info(png_const_infop info_ptr)
{
- memset(chunk_data, 0, sizeof(*chunk_data));
- chunk_data->info_ptr = info_ptr;
+ MEMZERO(user_chunk_data);
+ user_chunk_data.info_ptr = info_ptr;
}
static int
-set_chunk_location(png_structp png_ptr, user_chunk_info *chunk_data, int what)
+set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
{
int location;
- if ((chunk_data->location[0] & what) != 0 ||
- (chunk_data->location[1] & what) != 0)
- return 0; /* we already have one of these */
+ if ((data->location[0] & what) || (data->location[1] & what))
+ return 0; /* already have one of these */
- /* Find where we are (the code below zeroes info_ptr to indicate that the
+ /* Find where we are (the code below zeros info_ptr to indicate that the
* chunks before the first IDAT have been read.)
*/
- if (chunk_data->info_ptr == NULL) /* after IDAT */
+ if (data->info_ptr == NULL) /* after IDAT */
location = what | after_IDAT;
- else if (png_get_valid(png_ptr, chunk_data->info_ptr, PNG_INFO_PLTE) != 0)
+ else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE))
location = what | before_IDAT;
else
location = what | before_PLTE;
- if (chunk_data->location[0] == 0)
- chunk_data->location[0] = location;
+ if (data->location[0] == 0)
+ data->location[0] = location;
else
- chunk_data->location[1] = location;
+ data->location[1] = location;
return 1; /* handled */
}
-static int PNGCBAPI
-read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
+static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
+ png_unknown_chunkp chunk)
{
- user_chunk_info *my_user_chunk_data =
- (user_chunk_info*)png_get_user_chunk_ptr(png_ptr);
+ struct user_chunk_data *my_user_chunk_data =
+ (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
if (my_user_chunk_data == NULL)
- png_error(png_ptr, "lost pointer to user chunk data");
+ png_error(png_ptr, "lost user chunk pointer");
/* Return one of the following:
- * return -n; chunk had an error
- * return 0; did not recognize
- * return n; success
+ * return (-n); chunk had an error
+ * return (0); did not recognize
+ * return (n); success
*
* The unknown chunk structure contains the chunk data:
* png_byte name[5];
* png_byte *data;
- * size_t size;
+ * png_size_t size;
*
* Note that libpng has already taken care of the CRC handling.
*/
@@ -717,73 +685,73 @@ read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
{
/* Found sTER chunk */
if (chunk->size != 1)
- return -1; /* Error return */
+ return (-1); /* Error return */
if (chunk->data[0] != 0 && chunk->data[0] != 1)
- return -1; /* Invalid mode */
+ return (-1); /* Invalid mode */
- if (set_chunk_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
+ if (set_location(png_ptr, my_user_chunk_data, have_sTER))
{
- my_user_chunk_data->sTER_mode = chunk->data[0];
- return 1;
+ my_user_chunk_data->sTER_mode=chunk->data[0];
+ return (1);
}
else
- return 0; /* duplicate sTER - give it to libpng */
+ return (0); /* duplicate sTER - give it to libpng */
}
if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
- return 0; /* Did not recognize */
+ return (0); /* Did not recognize */
/* Found ImageMagick vpAg chunk */
if (chunk->size != 9)
- return -1; /* Error return */
+ return (-1); /* Error return */
- if (set_chunk_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
- return 0; /* duplicate vpAg */
+ if (!set_location(png_ptr, my_user_chunk_data, have_vpAg))
+ return (0); /* duplicate vpAg */
my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);
my_user_chunk_data->vpAg_units = chunk->data[8];
- return 1;
+ return (1);
}
#ifdef PNG_WRITE_SUPPORTED
static void
-write_sTER_chunk(png_structp write_ptr, user_chunk_info *data)
+write_sTER_chunk(png_structp write_ptr)
{
- png_byte sTER[5] = {115, 84, 69, 82, '\0'};
+ png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
- if (verbose != 0)
- fprintf(STDERR, "\n stereo mode = %d\n", data->sTER_mode);
+ if (verbose)
+ fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode);
- png_write_chunk(write_ptr, sTER, &data->sTER_mode, 1);
+ png_write_chunk(write_ptr, png_sTER, &user_chunk_data.sTER_mode, 1);
}
static void
-write_vpAg_chunk(png_structp write_ptr, user_chunk_info *data)
+write_vpAg_chunk(png_structp write_ptr)
{
- png_byte vpAg[5] = {118, 112, 65, 103, '\0'};
+ png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'};
png_byte vpag_chunk_data[9];
- if (verbose != 0)
+ if (verbose)
fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
- (unsigned long)data->vpAg_width,
- (unsigned long)data->vpAg_height,
- data->vpAg_units);
+ (unsigned long)user_chunk_data.vpAg_width,
+ (unsigned long)user_chunk_data.vpAg_height,
+ user_chunk_data.vpAg_units);
- png_save_uint_32(vpag_chunk_data, data->vpAg_width);
- png_save_uint_32(vpag_chunk_data + 4, data->vpAg_height);
- vpag_chunk_data[8] = data->vpAg_units;
- png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);
+ png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
+ png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
+ vpag_chunk_data[8] = user_chunk_data.vpAg_units;
+ png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9);
}
static void
-write_chunks(png_structp write_ptr, user_chunk_info *data, int location)
+write_chunks(png_structp write_ptr, int location)
{
int i;
@@ -793,17 +761,17 @@ write_chunks(png_structp write_ptr, user_chunk_info *data, int location)
* vpAg chunks, resulting in an error later. This is not worth worrying
* about - the chunks should not be duplicated!
*/
- for (i = 0; i < 2; ++i)
+ for (i=0; i<2; ++i)
{
- if (data->location[i] == (location | have_sTER))
- write_sTER_chunk(write_ptr, data);
+ if (user_chunk_data.location[i] == (location | have_sTER))
+ write_sTER_chunk(write_ptr);
- else if (data->location[i] == (location | have_vpAg))
- write_vpAg_chunk(write_ptr, data);
+ else if (user_chunk_data.location[i] == (location | have_vpAg))
+ write_vpAg_chunk(write_ptr);
}
}
-#endif /* WRITE */
-#else /* !READ_USER_CHUNKS */
+#endif /* PNG_WRITE_SUPPORTED */
+#else /* !PNG_READ_USER_CHUNKS_SUPPORTED */
# define write_chunks(pp,loc) ((void)0)
#endif
/* END of code to demonstrate user chunk support */
@@ -814,8 +782,8 @@ write_chunks(png_structp write_ptr, user_chunk_info *data, int location)
*/
#ifdef PNG_TEXT_SUPPORTED
static void
-pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
- int num_text)
+pngtest_check_text_support(png_const_structp png_ptr, png_textp text_ptr,
+ int num_text)
{
while (num_text > 0)
{
@@ -827,8 +795,6 @@ pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
case PNG_TEXT_COMPRESSION_zTXt:
# ifndef PNG_WRITE_zTXt_SUPPORTED
++unsupported_chunks;
- /* In libpng 1.7 this now does an app-error, so stop it: */
- text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
# endif
break;
@@ -836,7 +802,6 @@ pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
case PNG_ITXT_COMPRESSION_zTXt:
# ifndef PNG_WRITE_iTXt_SUPPORTED
++unsupported_chunks;
- text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
# endif
break;
@@ -852,10 +817,10 @@ pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
/* Test one file */
static int
-test_one_file(const char *inname, const char *outname)
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
{
- static FILE *fpin;
- static FILE *fpout; /* "static" prevents setjmp corruption */
+ static png_FILE_p fpin;
+ static png_FILE_p fpout; /* "static" prevents setjmp corruption */
pngtest_error_parameters error_parameters;
png_structp read_ptr;
png_infop read_info_ptr, end_info_ptr;
@@ -863,20 +828,16 @@ test_one_file(const char *inname, const char *outname)
png_structp write_ptr;
png_infop write_info_ptr;
png_infop write_end_info_ptr;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- int interlace_preserved = 1;
-#endif /* WRITE_FILTER */
-#else /* !WRITE */
+#else
png_structp write_ptr = NULL;
png_infop write_info_ptr = NULL;
png_infop write_end_info_ptr = NULL;
-#endif /* !WRITE */
+#endif
png_bytep row_buf;
png_uint_32 y;
png_uint_32 width, height;
+ int num_pass, pass;
int bit_depth, color_type;
- user_chunk_info my_user_chunk_data;
- int pass, num_passes;
row_buf = NULL;
error_parameters.file_name = inname;
@@ -884,39 +845,39 @@ test_one_file(const char *inname, const char *outname)
if ((fpin = fopen(inname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find input file %s\n", inname);
- return 1;
+ return (1);
}
if ((fpout = fopen(outname, "wb")) == NULL)
{
fprintf(STDERR, "Could not open output file %s\n", outname);
- fclose(fpin);
- return 1;
+ FCLOSE(fpin);
+ return (1);
}
pngtest_debug("Allocating read and write structures");
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
read_ptr =
- png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
- NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+ png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+ NULL, NULL, NULL, png_debug_malloc, png_debug_free);
#else
read_ptr =
- png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
#endif
png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
- pngtest_warning);
+ pngtest_warning);
#ifdef PNG_WRITE_SUPPORTED
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
write_ptr =
- png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
- NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+ png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+ NULL, NULL, NULL, png_debug_malloc, png_debug_free);
#else
write_ptr =
- png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
#endif
png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
- pngtest_warning);
+ pngtest_warning);
#endif
pngtest_debug("Allocating read_info, write_info and end_info structures");
read_info_ptr = png_create_info_struct(read_ptr);
@@ -927,9 +888,9 @@ test_one_file(const char *inname, const char *outname)
#endif
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
- init_user_chunk_info(read_info_ptr, &my_user_chunk_data);
- png_set_read_user_chunk_fn(read_ptr, &my_user_chunk_data,
- read_user_chunk_callback);
+ init_callback_info(read_info_ptr);
+ png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
+ read_user_chunk_callback);
#endif
#ifdef PNG_SETJMP_SUPPORTED
@@ -939,18 +900,14 @@ test_one_file(const char *inname, const char *outname)
fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
png_free(read_ptr, row_buf);
row_buf = NULL;
- if (verbose != 0)
- fprintf(STDERR, " destroy read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
- if (verbose != 0)
- fprintf(STDERR, " destroy write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
- fclose(fpin);
- fclose(fpout);
- return 1;
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
}
#ifdef PNG_WRITE_SUPPORTED
@@ -959,32 +916,27 @@ test_one_file(const char *inname, const char *outname)
if (setjmp(png_jmpbuf(write_ptr)))
{
fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
- png_free(read_ptr, row_buf);
- row_buf = NULL;
- if (verbose != 0)
- fprintf(STDERR, " destroying read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
- if (verbose != 0)
- fprintf(STDERR, " destroying write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
png_destroy_write_struct(&write_ptr, &write_info_ptr);
- fclose(fpin);
- fclose(fpout);
- return 1;
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
}
#endif
#endif
-#ifdef PNG_BENIGN_ERRORS_SUPPORTED
- if (strict != 0)
+ if (strict)
{
/* Treat png_benign_error() as errors on read */
png_set_benign_errors(read_ptr, 0);
-# ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_SUPPORTED
/* Treat them as errors on write */
png_set_benign_errors(write_ptr, 0);
-# endif
+#endif
/* if strict is not set, then app warnings and errors are treated as
* warnings in release builds, but not in unstable builds; this can be
@@ -992,25 +944,15 @@ test_one_file(const char *inname, const char *outname)
*/
}
- else if (relaxed != 0)
+ else if (relaxed)
{
/* Allow application (pngtest) errors and warnings to pass */
png_set_benign_errors(read_ptr, 1);
- /* Turn off CRC checking while reading */
- png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
-
-#ifdef PNG_IGNORE_ADLER32
- /* Turn off ADLER32 checking while reading */
- png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
-#endif
-
-# ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_SUPPORTED
png_set_benign_errors(write_ptr, 1);
-# endif
-
+#endif
}
-#endif /* BENIGN_ERRORS */
pngtest_debug("Initializing input and output streams");
#ifdef PNG_STDIO_SUPPORTED
@@ -1023,9 +965,9 @@ test_one_file(const char *inname, const char *outname)
# ifdef PNG_WRITE_SUPPORTED
png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
# ifdef PNG_WRITE_FLUSH_SUPPORTED
- pngtest_flush);
+ pngtest_flush);
# else
- NULL);
+ NULL);
# endif
# endif
#endif
@@ -1047,7 +989,14 @@ test_one_file(const char *inname, const char *outname)
}
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
- png_set_read_user_transform_fn(read_ptr, read_user_callback);
+ {
+ int i;
+
+ for (i = 0; i<256; i++)
+ filters_used[i] = 0;
+
+ png_set_read_user_transform_fn(read_ptr, count_filters);
+ }
#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
zero_samples = 0;
@@ -1055,21 +1004,21 @@ test_one_file(const char *inname, const char *outname)
#endif
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
- /* Preserve all the unknown chunks, if possible. If this is disabled, then
+ /* Preserve all the unknown chunks, if possible. If this is disabled then,
* even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use
* libpng to *save* the unknown chunks on read (because we can't switch the
* save option on!)
*
- * Notice that if SET_UNKNOWN_CHUNKS is *not* supported, the reader will
- * discard all unknown chunks, and the writer will write them all.
+ * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all
+ * unknown chunks and write will write them all.
*/
#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
- NULL, 0);
+ NULL, 0);
#endif
#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
- NULL, 0);
+ NULL, 0);
#endif
#endif
@@ -1082,7 +1031,7 @@ test_one_file(const char *inname, const char *outname)
* remove the info_ptr (which is only used to determine position relative to
* PLTE) here to indicate that we are after the IDAT.
*/
- my_user_chunk_data.info_ptr = NULL;
+ user_chunk_data.info_ptr = NULL;
#endif
pngtest_debug("Transferring info struct");
@@ -1090,43 +1039,27 @@ test_one_file(const char *inname, const char *outname)
int interlace_type, compression_type, filter_type;
if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
- &color_type, &interlace_type, &compression_type, &filter_type) != 0)
+ &color_type, &interlace_type, &compression_type, &filter_type))
{
png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
- color_type, interlace_type, compression_type, filter_type);
- /* num_passes may not be available below if interlace support is not
- * provided by libpng for both read and write.
- */
- switch (interlace_type)
- {
- case PNG_INTERLACE_NONE:
- num_passes = 1;
- break;
-
- case PNG_INTERLACE_ADAM7:
- num_passes = 7;
- break;
-
- default:
- png_error(read_ptr, "invalid interlace type");
- /*NOT REACHED*/
- }
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ color_type, interlace_type, compression_type, filter_type);
+#else
+ color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#endif
}
-
- else
- png_error(read_ptr, "png_get_IHDR failed");
}
#ifdef PNG_FIXED_POINT_SUPPORTED
#ifdef PNG_cHRM_SUPPORTED
{
png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
- blue_y;
+ blue_y;
if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
- &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+ &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y))
{
png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
- red_y, green_x, green_y, blue_x, blue_y);
+ red_y, green_x, green_y, blue_x, blue_y);
}
}
#endif
@@ -1134,46 +1067,22 @@ test_one_file(const char *inname, const char *outname)
{
png_fixed_point gamma;
- if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
+ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
}
#endif
-#ifdef PNG_cLLI_SUPPORTED
- {
- png_uint_32 maxCLL;
- png_uint_32 maxFALL;
-
- if (png_get_cLLI_fixed(read_ptr, read_info_ptr, &maxCLL, &maxFALL) != 0)
- png_set_cLLI_fixed(write_ptr, write_info_ptr, maxCLL, maxFALL);
- }
-#endif
-#ifdef PNG_mDCV_SUPPORTED
- {
- png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
- blue_y;
- png_uint_32 maxDL;
- png_uint_32 minDL;
-
- if (png_get_mDCV_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
- &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y,
- &maxDL, &minDL) != 0)
- png_set_mDCV_fixed(write_ptr, write_info_ptr, white_x, white_y,
- red_x, red_y, green_x, green_y, blue_x, blue_y,
- maxDL, minDL);
- }
-#endif
#else /* Use floating point versions */
#ifdef PNG_FLOATING_POINT_SUPPORTED
#ifdef PNG_cHRM_SUPPORTED
{
double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
- blue_y;
+ blue_y;
if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
- &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+ &red_y, &green_x, &green_y, &blue_x, &blue_y))
{
png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
- red_y, green_x, green_y, blue_x, blue_y);
+ red_y, green_x, green_y, blue_x, blue_y);
}
}
#endif
@@ -1181,50 +1090,12 @@ test_one_file(const char *inname, const char *outname)
{
double gamma;
- if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
+ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
png_set_gAMA(write_ptr, write_info_ptr, gamma);
}
#endif
-#ifdef PNG_cLLI_SUPPORTED
- {
- double maxCLL;
- double maxFALL;
-
- if (png_get_cLLI(read_ptr, read_info_ptr, &maxCLL, &maxFALL) != 0)
- png_set_cLLI(write_ptr, write_info_ptr, maxCLL, maxFALL);
- }
-#endif
-#ifdef PNG_mDCV_SUPPORTED
- {
- double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
- double maxDL;
- double minDL;
-
- if (png_get_mDCV(read_ptr, read_info_ptr, &white_x, &white_y,
- &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y,
- &maxDL, &minDL) != 0)
- png_set_mDCV(write_ptr, write_info_ptr, white_x, white_y,
- red_x, red_y, green_x, green_y, blue_x, blue_y,
- maxDL, minDL);
- }
-#endif
#endif /* Floating point */
#endif /* Fixed point */
-#ifdef PNG_cICP_SUPPORTED
- {
- png_byte colour_primaries;
- png_byte transfer_function;
- png_byte matrix_coefficients;
- png_byte video_full_range_flag;
-
- if (png_get_cICP(read_ptr, read_info_ptr,
- &colour_primaries, &transfer_function,
- &matrix_coefficients, &video_full_range_flag) != 0)
- png_set_cICP(write_ptr, write_info_ptr,
- colour_primaries, transfer_function,
- matrix_coefficients, video_full_range_flag);
- }
-#endif
#ifdef PNG_iCCP_SUPPORTED
{
png_charp name;
@@ -1233,10 +1104,10 @@ test_one_file(const char *inname, const char *outname)
int compression_type;
if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
- &profile, &proflen) != 0)
+ &profile, &proflen))
{
png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
- profile, proflen);
+ profile, proflen);
}
}
#endif
@@ -1244,7 +1115,7 @@ test_one_file(const char *inname, const char *outname)
{
int intent;
- if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
+ if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
png_set_sRGB(write_ptr, write_info_ptr, intent);
}
#endif
@@ -1252,30 +1123,16 @@ test_one_file(const char *inname, const char *outname)
png_colorp palette;
int num_palette;
- if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
+ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
}
#ifdef PNG_bKGD_SUPPORTED
{
png_color_16p background;
- if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
- png_set_bKGD(write_ptr, write_info_ptr, background);
- }
-#endif
-#ifdef PNG_READ_eXIf_SUPPORTED
- {
- png_bytep exif = NULL;
- png_uint_32 exif_length;
-
- if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
+ if (png_get_bKGD(read_ptr, read_info_ptr, &background))
{
- if (exif_length > 1)
- fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
- (unsigned long)exif_length);
-# ifdef PNG_WRITE_eXIf_SUPPORTED
- png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
-# endif
+ png_set_bKGD(write_ptr, write_info_ptr, background);
}
}
#endif
@@ -1283,7 +1140,7 @@ test_one_file(const char *inname, const char *outname)
{
png_uint_16p hist;
- if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
+ if (png_get_hIST(read_ptr, read_info_ptr, &hist))
png_set_hIST(write_ptr, write_info_ptr, hist);
}
#endif
@@ -1293,8 +1150,10 @@ test_one_file(const char *inname, const char *outname)
int unit_type;
if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
- &unit_type) != 0)
+ &unit_type))
+ {
png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+ }
}
#endif
#ifdef PNG_pCAL_SUPPORTED
@@ -1305,9 +1164,11 @@ test_one_file(const char *inname, const char *outname)
int type, nparams;
if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
- &nparams, &units, ¶ms) != 0)
+ &nparams, &units, ¶ms))
+ {
png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
- nparams, units, params);
+ nparams, units, params);
+ }
}
#endif
#ifdef PNG_pHYs_SUPPORTED
@@ -1315,8 +1176,7 @@ test_one_file(const char *inname, const char *outname)
png_uint_32 res_x, res_y;
int unit_type;
- if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
- &unit_type) != 0)
+ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
}
#endif
@@ -1324,7 +1184,7 @@ test_one_file(const char *inname, const char *outname)
{
png_color_8p sig_bit;
- if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
+ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
}
#endif
@@ -1336,8 +1196,10 @@ test_one_file(const char *inname, const char *outname)
double scal_width, scal_height;
if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
- &scal_height) != 0)
+ &scal_height))
+ {
png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
}
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
@@ -1346,7 +1208,7 @@ test_one_file(const char *inname, const char *outname)
png_charp scal_width, scal_height;
if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
- &scal_height) != 0)
+ &scal_height))
{
png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
scal_height);
@@ -1355,17 +1217,6 @@ test_one_file(const char *inname, const char *outname)
#endif
#endif
#endif
-
-#ifdef PNG_sPLT_SUPPORTED
- {
- png_sPLT_tp entries;
-
- int num_entries = png_get_sPLT(read_ptr, read_info_ptr, &entries);
- if (num_entries != 0)
- png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries);
- }
-#endif
-
#ifdef PNG_TEXT_SUPPORTED
{
png_textp text_ptr;
@@ -1377,15 +1228,15 @@ test_one_file(const char *inname, const char *outname)
pngtest_check_text_support(read_ptr, text_ptr, num_text);
- if (verbose != 0)
+ if (verbose)
{
int i;
- fprintf(STDERR,"\n");
- for (i = 0; i < num_text; i++)
+ printf("\n");
+ for (i=0; i 0)
- pass_height = PNG_PASS_ROWS(height, pass);
-
- else
- pass_height = 0;
- }
-
- else /* not interlaced */
- pass_height = height;
-# else
-# define pass_height height
-# endif
-
pngtest_debug1("Writing row data for pass %d", pass);
- for (y = 0; y < pass_height; y++)
+ for (y = 0; y < height; y++)
{
+#ifndef SINGLE_ROWBUF_ALLOC
pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
-
row_buf = (png_bytep)png_malloc(read_ptr,
- png_get_rowbytes(read_ptr, read_info_ptr));
+ png_get_rowbytes(read_ptr, read_info_ptr));
- pngtest_debug2("\t%p (%lu bytes)", row_buf,
- (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
+ pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+#endif /* !SINGLE_ROWBUF_ALLOC */
png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
#ifdef PNG_WRITE_SUPPORTED
@@ -1541,21 +1381,21 @@ test_one_file(const char *inname, const char *outname)
t_encode += (t_stop - t_start);
t_start = t_stop;
#endif
-#endif /* WRITE */
+#endif /* PNG_WRITE_SUPPORTED */
+#ifndef SINGLE_ROWBUF_ALLOC
pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
png_free(read_ptr, row_buf);
row_buf = NULL;
+#endif /* !SINGLE_ROWBUF_ALLOC */
}
}
-#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
-# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
- png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
-# endif
-# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
- png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
-# endif
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
#endif
pngtest_debug("Reading and writing end_info data");
@@ -1572,15 +1412,15 @@ test_one_file(const char *inname, const char *outname)
pngtest_check_text_support(read_ptr, text_ptr, num_text);
- if (verbose != 0)
+ if (verbose)
{
int i;
- fprintf(STDERR,"\n");
- for (i = 0; i < num_text; i++)
+ printf("\n");
+ for (i=0; i 1)
- fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
- (unsigned long)exif_length);
-# ifdef PNG_WRITE_eXIf_SUPPORTED
- png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
-# endif
- }
- }
-#endif
#ifdef PNG_tIME_SUPPORTED
{
png_timep mod_time;
- if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
+ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
{
png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
#ifdef PNG_TIME_RFC1123_SUPPORTED
- if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
+ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time))
tIME_string[(sizeof tIME_string) - 1] = '\0';
else
@@ -1622,7 +1446,7 @@ test_one_file(const char *inname, const char *outname)
}
tIME_chunk_present++;
-#endif /* TIME_RFC1123 */
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
}
}
#endif
@@ -1630,11 +1454,25 @@ test_one_file(const char *inname, const char *outname)
{
png_unknown_chunkp unknowns;
int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
- &unknowns);
+ &unknowns);
- if (num_unknowns != 0)
+ if (num_unknowns)
+ {
png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
- num_unknowns);
+ num_unknowns);
+#if PNG_LIBPNG_VER < 10600
+ /* Copy the locations from the read_info_ptr. The automatically
+ * generated locations in write_end_info_ptr are wrong prior to 1.6.0
+ * because they are reset from the write pointer (removed in 1.6.0).
+ */
+ {
+ int i;
+ for (i = 0; i < num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+ unknowns[i].location);
+ }
+#endif
+ }
}
#endif
@@ -1653,35 +1491,40 @@ test_one_file(const char *inname, const char *outname)
* There seems to be no way round this, however vpAg/sTER are not expected
* after IDAT.
*/
- write_chunks(write_ptr, &my_user_chunk_data, after_IDAT);
+ write_chunks(write_ptr, after_IDAT);
png_write_end(write_ptr, write_end_info_ptr);
#endif
#ifdef PNG_EASY_ACCESS_SUPPORTED
- if (verbose != 0)
+ if (verbose)
{
png_uint_32 iwidth, iheight;
iwidth = png_get_image_width(write_ptr, write_info_ptr);
iheight = png_get_image_height(write_ptr, write_info_ptr);
fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
- (unsigned long)iwidth, (unsigned long)iheight);
+ (unsigned long)iwidth, (unsigned long)iheight);
}
#endif
pngtest_debug("Destroying data structs");
- pngtest_debug("Destroying read_ptr, read_info_ptr, end_info_ptr");
+#ifdef SINGLE_ROWBUF_ALLOC
+ pngtest_debug("destroying row_buf for read_ptr");
+ png_free(read_ptr, row_buf);
+ row_buf = NULL;
+#endif /* SINGLE_ROWBUF_ALLOC */
+ pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
- pngtest_debug("Destroying write_end_info_ptr");
+ pngtest_debug("destroying write_end_info_ptr");
png_destroy_info_struct(write_ptr, &write_end_info_ptr);
- pngtest_debug("Destroying write_ptr, write_info_ptr");
+ pngtest_debug("destroying write_ptr, write_info_ptr");
png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
pngtest_debug("Destruction complete.");
- fclose(fpin);
- fclose(fpout);
+ FCLOSE(fpin);
+ FCLOSE(fpout);
/* Summarize any warnings or errors and in 'strict' mode fail the test.
* Unsupported chunks can result in warnings, in that case ignore the strict
@@ -1693,110 +1536,108 @@ test_one_file(const char *inname, const char *outname)
* above, but this is safe.
*/
fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)",
- inname, error_count, warning_count);
+ inname, error_count, warning_count);
if (strict != 0)
- return 1;
+ return (1);
}
# ifdef PNG_WRITE_SUPPORTED
- /* If there is no write support nothing was written! */
+ /* If there we no write support nothing was written! */
else if (unsupported_chunks > 0)
{
fprintf(STDERR, "\n %s: unsupported chunks (%d)%s",
- inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
+ inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
}
# endif
else if (warning_count > 0)
{
fprintf(STDERR, "\n %s: %d libpng warnings found",
- inname, warning_count);
+ inname, warning_count);
if (strict != 0)
- return 1;
+ return (1);
}
pngtest_debug("Opening files for comparison");
if ((fpin = fopen(inname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find file %s\n", inname);
- return 1;
+ return (1);
}
if ((fpout = fopen(outname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find file %s\n", outname);
- fclose(fpin);
- return 1;
+ FCLOSE(fpin);
+ return (1);
}
-#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\
- defined (PNG_WRITE_FILTER_SUPPORTED)
- if (interlace_preserved != 0) /* else the files will be changed */
+#ifdef PNG_WRITE_SUPPORTED /* else nothing was written */
{
+ int wrote_question = 0;
+
for (;;)
{
- static int wrote_question = 0;
- size_t num_in, num_out;
+ png_size_t num_in, num_out;
char inbuf[256], outbuf[256];
+
num_in = fread(inbuf, 1, sizeof inbuf, fpin);
num_out = fread(outbuf, 1, sizeof outbuf, fpout);
if (num_in != num_out)
{
fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
- inname, outname);
+ inname, outname);
if (wrote_question == 0 && unsupported_chunks == 0)
{
fprintf(STDERR,
- " Was %s written with the same maximum IDAT"
- " chunk size (%d bytes),",
- inname, PNG_ZBUF_SIZE);
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
+ inname, PNG_ZBUF_SIZE);
fprintf(STDERR,
- "\n filtering heuristic (libpng default), compression");
+ "\n filtering heuristic (libpng default), compression");
fprintf(STDERR,
- " level (zlib default),\n and zlib version (%s)?\n\n",
- ZLIB_VERSION);
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
wrote_question = 1;
}
- fclose(fpin);
- fclose(fpout);
+ FCLOSE(fpin);
+ FCLOSE(fpout);
if (strict != 0 && unsupported_chunks == 0)
- return 1;
+ return (1);
else
- return 0;
+ return (0);
}
- if (num_in == 0)
+ if (!num_in)
break;
if (memcmp(inbuf, outbuf, num_in))
{
fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
- outname);
+ outname);
if (wrote_question == 0 && unsupported_chunks == 0)
{
fprintf(STDERR,
- " Was %s written with the same maximum"
- " IDAT chunk size (%d bytes),",
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
inname, PNG_ZBUF_SIZE);
fprintf(STDERR,
- "\n filtering heuristic (libpng default), compression");
+ "\n filtering heuristic (libpng default), compression");
fprintf(STDERR,
- " level (zlib default),\n and zlib version (%s)?\n\n",
+ " level (zlib default),\n and zlib version (%s)?\n\n",
ZLIB_VERSION);
wrote_question = 1;
}
- fclose(fpin);
- fclose(fpout);
+ FCLOSE(fpin);
+ FCLOSE(fpout);
/* NOTE: the unsupported_chunks escape is permitted here because
* unsupported text chunk compression will result in the compression
@@ -1804,28 +1645,28 @@ test_one_file(const char *inname, const char *outname)
* can be exactly the same size!
*/
if (strict != 0 && unsupported_chunks == 0)
- return 1;
+ return (1);
else
- return 0;
+ return (0);
}
}
}
-#endif /* WRITE && WRITE_FILTER */
+#endif /* PNG_WRITE_SUPPORTED */
- fclose(fpin);
- fclose(fpout);
+ FCLOSE(fpin);
+ FCLOSE(fpout);
- return 0;
+ return (0);
}
/* Input and output filenames */
#ifdef RISCOS
-static const char *inname = "pngtest/png";
-static const char *outname = "pngout/png";
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
#else
-static const char *inname = "pngtest.png";
-static const char *outname = "pngout.png";
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
#endif
int
@@ -1834,19 +1675,17 @@ main(int argc, char *argv[])
int multiple = 0;
int ierror = 0;
- png_structp dummy_ptr;
-
fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
fprintf(STDERR, "%s", png_get_copyright(NULL));
/* Show the version of libpng used in building the library */
fprintf(STDERR, " library (%lu):%s",
- (unsigned long)png_access_version_number(),
- png_get_header_version(NULL));
+ (unsigned long)png_access_version_number(),
+ png_get_header_version(NULL));
/* Show the version of libpng used in building the application */
fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
- PNG_HEADER_VERSION_STRING);
+ PNG_HEADER_VERSION_STRING);
/* Do some consistency checking on the memory allocation settings, I'm
* not sure this matters, but it is nice to know, the first of these
@@ -1861,11 +1700,12 @@ main(int argc, char *argv[])
fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
#endif
- if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING) != 0)
+ if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
{
- fprintf(STDERR, "Warning: mismatching versions of png.h and png.c\n");
- fprintf(STDERR, " png.h version string: %s\n", PNG_LIBPNG_VER_STRING);
- fprintf(STDERR, " png.c version string: %s\n\n", png_libpng_ver);
+ fprintf(STDERR,
+ "Warning: versions are different between png.h and png.c\n");
+ fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
++ierror;
}
@@ -1899,7 +1739,6 @@ main(int argc, char *argv[])
inname = argv[2];
strict++;
relaxed = 0;
- multiple = 1;
}
else if (strcmp(argv[1], "--relaxed") == 0)
@@ -1909,17 +1748,6 @@ main(int argc, char *argv[])
inname = argv[2];
strict = 0;
relaxed++;
- multiple = 1;
- }
- else if (strcmp(argv[1], "--xfail") == 0)
- {
- status_dots_requested = 0;
- verbose = 1;
- inname = argv[2];
- strict = 0;
- xfail++;
- relaxed++;
- multiple = 1;
}
else
@@ -1929,79 +1757,79 @@ main(int argc, char *argv[])
}
}
- if (multiple == 0 && argc == 3 + verbose)
- outname = argv[2 + verbose];
+ if (!multiple && argc == 3 + verbose)
+ outname = argv[2 + verbose];
- if ((multiple == 0 && argc > 3 + verbose) ||
- (multiple != 0 && argc < 2))
+ if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
{
- fprintf(STDERR,
- "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
- argv[0], argv[0]);
- fprintf(STDERR,
- " reads/writes one PNG file (without -m) or multiple files (-m)\n");
- fprintf(STDERR,
- " with -m %s is used as a temporary file\n", outname);
- exit(1);
+ fprintf(STDERR,
+ "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+ argv[0], argv[0]);
+ fprintf(STDERR,
+ " reads/writes one PNG file (without -m) or multiple files (-m)\n");
+ fprintf(STDERR,
+ " with -m %s is used as a temporary file\n", outname);
+ exit(1);
}
- if (multiple != 0)
+ if (multiple)
{
int i;
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
int allocation_now = current_allocation;
#endif
- for (i = 2; i < argc; ++i)
+ for (i=2; i 0
- fprintf(STDERR, "\n");
-#endif
kerror = test_one_file(argv[i], outname);
if (kerror == 0)
{
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ int k;
+#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
fprintf(STDERR, "\n PASS (%lu zero samples)\n",
- (unsigned long)zero_samples);
+ (unsigned long)zero_samples);
#else
fprintf(STDERR, " PASS\n");
#endif
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ for (k = 0; k<256; k++)
+ if (filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k, (unsigned long)filters_used[k]);
+#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
- if (tIME_chunk_present != 0)
- fprintf(STDERR, " tIME = %s\n", tIME_string);
+ if (tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n", tIME_string);
- tIME_chunk_present = 0;
-#endif /* TIME_RFC1123 */
+ tIME_chunk_present = 0;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
}
else
{
- if (xfail)
- fprintf(STDERR, " XFAIL\n");
- else
- {
- fprintf(STDERR, " FAIL\n");
- ierror += kerror;
- }
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
}
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
if (allocation_now != current_allocation)
fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
- current_allocation - allocation_now);
+ current_allocation - allocation_now);
if (current_allocation != 0)
{
memory_infop pinfo = pinformation;
fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
- current_allocation);
+ current_allocation);
while (pinfo != NULL)
{
- fprintf(STDERR, " %lu bytes at %p\n",
- (unsigned long)pinfo->size,
- pinfo->pointer);
+ fprintf(STDERR, " %lu bytes at %x\n",
+ (unsigned long)pinfo->size,
+ (unsigned int)pinfo->pointer);
pinfo = pinfo->next;
}
}
@@ -2009,20 +1837,20 @@ main(int argc, char *argv[])
}
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
fprintf(STDERR, " Current memory allocation: %10d bytes\n",
- current_allocation);
+ current_allocation);
fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
- maximum_allocation);
+ maximum_allocation);
fprintf(STDERR, " Total memory allocation: %10d bytes\n",
- total_allocation);
+ total_allocation);
fprintf(STDERR, " Number of allocations: %10d\n",
- num_allocations);
+ num_allocations);
#endif
}
else
{
int i;
- for (i = 0; i < 3; ++i)
+ for (i = 0; i<3; ++i)
{
int kerror;
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
@@ -2035,12 +1863,7 @@ main(int argc, char *argv[])
status_dots_requested = 0;
if (i == 0 || verbose == 1 || ierror != 0)
- {
fprintf(STDERR, "\n Testing %s:", inname);
-#if PNG_DEBUG > 0
- fprintf(STDERR, "\n");
-#endif
- }
kerror = test_one_file(inname, outname);
@@ -2048,53 +1871,52 @@ main(int argc, char *argv[])
{
if (verbose == 1 || i == 2)
{
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ int k;
+#endif
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
fprintf(STDERR, "\n PASS (%lu zero samples)\n",
- (unsigned long)zero_samples);
+ (unsigned long)zero_samples);
#else
fprintf(STDERR, " PASS\n");
#endif
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ for (k = 0; k<256; k++)
+ if (filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k, (unsigned long)filters_used[k]);
+#endif
#ifdef PNG_TIME_RFC1123_SUPPORTED
if (tIME_chunk_present != 0)
fprintf(STDERR, " tIME = %s\n", tIME_string);
-#endif /* TIME_RFC1123 */
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
}
}
else
{
if (verbose == 0 && i != 2)
- {
fprintf(STDERR, "\n Testing %s:", inname);
-#if PNG_DEBUG > 0
- fprintf(STDERR, "\n");
-#endif
- }
- if (xfail)
- fprintf(STDERR, " XFAIL\n");
- else
- {
- fprintf(STDERR, " FAIL\n");
- ierror += kerror;
- }
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
}
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
if (allocation_now != current_allocation)
fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
- current_allocation - allocation_now);
+ current_allocation - allocation_now);
if (current_allocation != 0)
{
memory_infop pinfo = pinformation;
fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
- current_allocation);
+ current_allocation);
while (pinfo != NULL)
{
- fprintf(STDERR, " %lu bytes at %p\n",
- (unsigned long)pinfo->size, pinfo->pointer);
+ fprintf(STDERR, " %lu bytes at %x\n",
+ (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
pinfo = pinfo->next;
}
}
@@ -2102,13 +1924,13 @@ main(int argc, char *argv[])
}
#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
fprintf(STDERR, " Current memory allocation: %10d bytes\n",
- current_allocation);
+ current_allocation);
fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
- maximum_allocation);
+ maximum_allocation);
fprintf(STDERR, " Total memory allocation: %10d bytes\n",
- total_allocation);
+ total_allocation);
fprintf(STDERR, " Number of allocations: %10d\n",
- num_allocations);
+ num_allocations);
#endif
}
@@ -2117,13 +1939,13 @@ main(int argc, char *argv[])
t_misc += (t_stop - t_start);
t_start = t_stop;
fprintf(STDERR, " CPU time used = %.3f seconds",
- (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+ (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
fprintf(STDERR, " (decoding %.3f,\n",
- t_decode/(float)CLOCKS_PER_SEC);
+ t_decode/(float)CLOCKS_PER_SEC);
fprintf(STDERR, " encoding %.3f ,",
- t_encode/(float)CLOCKS_PER_SEC);
+ t_encode/(float)CLOCKS_PER_SEC);
fprintf(STDERR, " other %.3f seconds)\n\n",
- t_misc/(float)CLOCKS_PER_SEC);
+ t_misc/(float)CLOCKS_PER_SEC);
#endif
if (ierror == 0)
@@ -2132,35 +1954,18 @@ main(int argc, char *argv[])
else
fprintf(STDERR, " libpng FAILS test\n");
- dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-#ifdef PNG_USER_LIMITS_SUPPORTED
- fprintf(STDERR, " Default limits:\n");
- fprintf(STDERR, " width_max = %lu\n",
- (unsigned long) png_get_user_width_max(dummy_ptr));
- fprintf(STDERR, " height_max = %lu\n",
- (unsigned long) png_get_user_height_max(dummy_ptr));
- if (png_get_chunk_cache_max(dummy_ptr) == 0)
- fprintf(STDERR, " cache_max = unlimited\n");
- else
- fprintf(STDERR, " cache_max = %lu\n",
- (unsigned long) png_get_chunk_cache_max(dummy_ptr));
- if (png_get_chunk_malloc_max(dummy_ptr) == 0)
- fprintf(STDERR, " malloc_max = unlimited\n");
- else
- fprintf(STDERR, " malloc_max = %lu\n",
- (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
-#endif
- png_destroy_read_struct(&dummy_ptr, NULL, NULL);
-
- return (ierror != 0);
+ return (int)(ierror != 0);
}
#else
int
main(void)
{
fprintf(STDERR,
- " test ignored because libpng was not built with read support\n");
+ " test ignored because libpng was not built with read support\n");
/* And skip this test */
- return SKIP;
+ return 77;
}
#endif
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef png_libpng_version_1_6_2 Your_png_h_is_not_version_1_6_2;
diff --git a/Windows_Libs/Dev/Render/libpng/pngtrans.c b/Windows_Libs/Dev/Render/libpng/pngtrans.c
index 19f5c64..8f8bc5d 100644
--- a/Windows_Libs/Dev/Render/libpng/pngtrans.c
+++ b/Windows_Libs/Dev/Render/libpng/pngtrans.c
@@ -1,9 +1,10 @@
+
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
- * Copyright (c) 2018-2024 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -29,7 +30,7 @@ png_set_bgr(png_structrp png_ptr)
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Turn on 16-bit byte swapping */
+/* Turn on 16 bit byte swapping */
void PNGAPI
png_set_swap(png_structrp png_ptr)
{
@@ -56,9 +57,7 @@ png_set_packing(png_structrp png_ptr)
if (png_ptr->bit_depth < 8)
{
png_ptr->transformations |= PNG_PACK;
-# ifdef PNG_WRITE_SUPPORTED
- png_ptr->usr_bit_depth = 8;
-# endif
+ png_ptr->usr_bit_depth = 8;
}
}
#endif
@@ -99,13 +98,13 @@ png_set_interlace_handling(png_structrp png_ptr)
{
png_debug(1, "in png_set_interlace handling");
- if (png_ptr != 0 && png_ptr->interlaced != 0)
+ if (png_ptr && png_ptr->interlaced)
{
png_ptr->transformations |= PNG_INTERLACE;
- return 7;
+ return (7);
}
- return 1;
+ return (1);
}
#endif
@@ -126,7 +125,7 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
/* In libpng 1.6 it is possible to determine whether this is a read or write
* operation and therefore to do more checking here for a valid call.
*/
- if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
{
# ifdef PNG_READ_FILLER_SUPPORTED
/* On read png_set_filler is always valid, regardless of the base PNG
@@ -171,14 +170,13 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
* size!
*/
png_app_error(png_ptr,
- "png_set_filler is invalid for"
- " low bit depth gray output");
+ "png_set_filler is invalid for low bit depth gray output");
return;
}
default:
png_app_error(png_ptr,
- "png_set_filler: inappropriate color type");
+ "png_set_filler: inappropriate color type");
return;
}
# else
@@ -210,7 +208,7 @@ png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
png_set_filler(png_ptr, filler, filler_loc);
/* The above may fail to do anything. */
- if ((png_ptr->transformations & PNG_FILLER) != 0)
+ if (png_ptr->transformations & PNG_FILLER)
png_ptr->transformations |= PNG_ADD_ALPHA;
}
@@ -268,8 +266,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp = row;
- size_t i;
- size_t istop = row_info->rowbytes;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
@@ -282,8 +280,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
row_info->bit_depth == 8)
{
png_bytep rp = row;
- size_t i;
- size_t istop = row_info->rowbytes;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 2)
{
@@ -297,8 +295,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
row_info->bit_depth == 16)
{
png_bytep rp = row;
- size_t i;
- size_t istop = row_info->rowbytes;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 4)
{
@@ -313,7 +311,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
#ifdef PNG_16BIT_SUPPORTED
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swaps byte order on 16-bit depth images */
+/* Swaps byte order on 16 bit depth images */
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
@@ -327,16 +325,9 @@ png_do_swap(png_row_infop row_info, png_bytep row)
for (i = 0; i < istop; i++, rp += 2)
{
-#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
- /* Feature added to libpng-1.6.11 for testing purposes, not
- * enabled by default.
- */
- *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
-#else
png_byte t = *rp;
*rp = *(rp + 1);
*(rp + 1) = t;
-#endif
}
}
}
@@ -344,7 +335,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
-static const png_byte onebppswaptable[256] = {
+static PNG_CONST png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
@@ -379,7 +370,7 @@ static const png_byte onebppswaptable[256] = {
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
-static const png_byte twobppswaptable[256] = {
+static PNG_CONST png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
@@ -414,7 +405,7 @@ static const png_byte twobppswaptable[256] = {
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};
-static const png_byte fourbppswaptable[256] = {
+static PNG_CONST png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
@@ -478,7 +469,7 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
*rp = table[*rp];
}
}
-#endif /* PACKSWAP || WRITE_PACKSWAP */
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
@@ -497,8 +488,6 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
- png_debug(1, "in png_do_strip_channel");
-
/* At the start sp will point to the first byte to copy and dp to where
* it is copied to. ep always points just beyond the end of the row, so
* the loop simply copies (channels-1) channels until sp reaches ep.
@@ -512,35 +501,27 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
{
if (row_info->bit_depth == 8)
{
- if (at_start != 0) /* Skip initial filler */
+ if (at_start) /* Skip initial filler */
++sp;
else /* Skip initial channel and, for sp, the filler */
- {
- sp += 2; ++dp;
- }
+ sp += 2, ++dp;
/* For a 1 pixel wide image there is nothing to do */
while (sp < ep)
- {
- *dp++ = *sp; sp += 2;
- }
+ *dp++ = *sp, sp += 2;
row_info->pixel_depth = 8;
}
else if (row_info->bit_depth == 16)
{
- if (at_start != 0) /* Skip initial filler */
+ if (at_start) /* Skip initial filler */
sp += 2;
else /* Skip initial channel and, for sp, the filler */
- {
- sp += 4; dp += 2;
- }
+ sp += 4, dp += 2;
while (sp < ep)
- {
- *dp++ = *sp++; *dp++ = *sp; sp += 3;
- }
+ *dp++ = *sp++, *dp++ = *sp, sp += 3;
row_info->pixel_depth = 16;
}
@@ -560,37 +541,31 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
{
if (row_info->bit_depth == 8)
{
- if (at_start != 0) /* Skip initial filler */
+ if (at_start) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
- {
- sp += 4; dp += 3;
- }
+ sp += 4, dp += 3;
/* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep)
- {
- *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
- }
+ *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
row_info->pixel_depth = 24;
}
else if (row_info->bit_depth == 16)
{
- if (at_start != 0) /* Skip initial filler */
+ if (at_start) /* Skip initial filler */
sp += 2;
else /* Skip initial channels and, for sp, the filler */
- {
- sp += 8; dp += 6;
- }
+ sp += 8, dp += 6;
while (sp < ep)
{
/* Copy 6 bytes, skip 2 */
- *dp++ = *sp++; *dp++ = *sp++;
- *dp++ = *sp++; *dp++ = *sp++;
- *dp++ = *sp++; *dp++ = *sp; sp += 3;
+ *dp++ = *sp++, *dp++ = *sp++;
+ *dp++ = *sp++, *dp++ = *sp++;
+ *dp++ = *sp++, *dp++ = *sp, sp += 3;
}
row_info->pixel_depth = 48;
@@ -610,7 +585,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
return; /* The filler channel has gone already */
/* Fix the rowbytes value. */
- row_info->rowbytes = (size_t)(dp-row);
+ row_info->rowbytes = dp-row;
}
#endif
@@ -621,7 +596,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr");
- if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
{
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
@@ -691,7 +666,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
#endif
}
}
-#endif /* READ_BGR || WRITE_BGR */
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
@@ -699,8 +674,6 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
void /* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
{
- png_debug(1, "in png_do_check_palette_indexes");
-
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
{
@@ -710,7 +683,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* and this calculation is used because it avoids warnings that other
* forms produced on either GCC or MSVC.
*/
- int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
+ int padding = (-row_info->pixel_depth * row_info->width) & 7;
png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
switch (row_info->bit_depth)
@@ -722,7 +695,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
*/
for (; rp > png_ptr->row_buf; rp--)
{
- if ((*rp >> padding) != 0)
+ if (*rp >> padding != 0)
png_ptr->num_palette_max = 1;
padding = 0;
}
@@ -796,14 +769,14 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
}
}
}
-#endif /* CHECK_FOR_INVALID_INDEX */
+#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
void PNGAPI
-png_set_user_transform_info(png_structrp png_ptr, png_voidp user_transform_ptr,
- int user_transform_depth, int user_transform_channels)
+png_set_user_transform_info(png_structrp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
{
png_debug(1, "in png_set_user_transform_info");
@@ -815,7 +788,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp user_transform_ptr,
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
{
png_app_error(png_ptr,
- "info change after png_start_read_image or png_read_update_info");
+ "info change after png_start_read_image or png_read_update_info");
return;
}
#endif
@@ -836,7 +809,7 @@ png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
- return NULL;
+ return (NULL);
return png_ptr->user_transform_ptr;
}
@@ -846,7 +819,7 @@ png_get_user_transform_ptr(png_const_structrp png_ptr)
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structrp png_ptr)
{
- /* See the comments in png.h - this is the sub-image row when reading an
+ /* See the comments in png.h - this is the sub-image row when reading and
* interlaced image.
*/
if (png_ptr != NULL)
@@ -862,6 +835,7 @@ png_get_current_pass_number(png_const_structrp png_ptr)
return png_ptr->pass;
return 8; /* invalid */
}
-#endif /* USER_TRANSFORM_INFO */
-#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
-#endif /* READ || WRITE */
+#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
+#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
+ PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngwio.c b/Windows_Libs/Dev/Render/libpng/pngwio.c
index 96a3187..e3289df 100644
--- a/Windows_Libs/Dev/Render/libpng/pngwio.c
+++ b/Windows_Libs/Dev/Render/libpng/pngwio.c
@@ -1,9 +1,10 @@
+
/* pngwio.c - functions for data output
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -25,16 +26,16 @@
* writes to a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered writes. This should never be asked
- * to write more than 64K on a 16-bit machine.
+ * to write more than 64K on a 16 bit machine.
*/
void /* PRIVATE */
-png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
{
/* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
- length);
+ length);
else
png_error(png_ptr, "Call to NULL write function");
@@ -47,14 +48,14 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
* than changing the library.
*/
void PNGCBAPI
-png_default_write_data(png_structp png_ptr, png_bytep data, size_t length)
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
- size_t check;
+ png_size_t check;
if (png_ptr == NULL)
return;
- check = fwrite(data, 1, length, (FILE *)png_ptr->io_ptr);
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
if (check != length)
png_error(png_ptr, "Write Error");
@@ -77,12 +78,12 @@ png_flush(png_structrp png_ptr)
void PNGCBAPI
png_default_flush(png_structp png_ptr)
{
- FILE *io_ptr;
+ png_FILE_p io_ptr;
if (png_ptr == NULL)
return;
- io_ptr = png_voidcast(FILE *, png_ptr->io_ptr);
+ io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
fflush(io_ptr);
}
# endif
@@ -148,11 +149,8 @@ png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
# else
png_ptr->output_flush_fn = output_flush_fn;
# endif
-#else
- PNG_UNUSED(output_flush_fn)
-#endif /* WRITE_FLUSH */
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
-#ifdef PNG_READ_SUPPORTED
/* It is an error to read while writing a png file */
if (png_ptr->read_data_fn != NULL)
{
@@ -162,6 +160,5 @@ png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
"Can't set both read_data_fn and write_data_fn in the"
" same structure");
}
-#endif
}
-#endif /* WRITE */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngwrite.c b/Windows_Libs/Dev/Render/libpng/pngwrite.c
index 362a8c3..53aaa8c 100644
--- a/Windows_Libs/Dev/Render/libpng/pngwrite.c
+++ b/Windows_Libs/Dev/Render/libpng/pngwrite.c
@@ -1,9 +1,10 @@
+
/* pngwrite.c - general routines to write a PNG file
*
- * Copyright (c) 2018-2026 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -11,9 +12,9 @@
*/
#include "pngpriv.h"
-#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
# include
-#endif /* SIMPLIFIED_WRITE_STDIO */
+#endif
#ifdef PNG_WRITE_SUPPORTED
@@ -21,9 +22,9 @@
/* Write out all the unknown chunks for the current given location */
static void
write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
- unsigned int where)
+ unsigned int where)
{
- if (info_ptr->unknown_chunks_num != 0)
+ if (info_ptr->unknown_chunks_num)
{
png_const_unknown_chunkp up;
@@ -32,7 +33,7 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
for (up = info_ptr->unknown_chunks;
up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
++up)
- if ((up->location & where) != 0)
+ if (up->location & where)
{
/* If per-chunk unknown chunk handling is enabled use it, otherwise
* just write the chunks the application has set.
@@ -68,16 +69,16 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
}
}
}
-#endif /* WRITE_UNKNOWN_CHUNKS */
+#endif /* PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED */
/* Writes all the PNG information. This is the suggested way to use the
* library. If you have a new chunk to add, make a function to write it,
* and put it in the correct location here. If you want the chunk written
* after the image data, put it in png_write_end(). I strongly encourage
- * you to supply a PNG_INFO_ flag, and check info_ptr->valid before
- * writing the chunk, as that will keep the code from breaking if you want
- * to just write a plain PNG file. If you have long comments, I suggest
- * writing them in png_write_end(), and compressing them.
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
*/
void PNGAPI
png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
@@ -87,133 +88,100 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr == NULL || info_ptr == NULL)
return;
- if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
{
- /* Write PNG signature */
- png_write_sig(png_ptr);
+ /* Write PNG signature */
+ png_write_sig(png_ptr);
#ifdef PNG_MNG_FEATURES_SUPPORTED
- if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \
- png_ptr->mng_features_permitted != 0)
- {
- png_warning(png_ptr,
- "MNG features are not allowed in a PNG datastream");
- png_ptr->mng_features_permitted = 0;
- }
+ if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
+ (png_ptr->mng_features_permitted))
+ {
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+ png_ptr->mng_features_permitted = 0;
+ }
#endif
- /* Write IHDR information. */
- png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
- info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
- info_ptr->filter_type,
+ /* Write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
- info_ptr->interlace_type
+ info_ptr->interlace_type
#else
- 0
+ 0
#endif
- );
+ );
- /* The rest of these check to see if the valid field has the appropriate
- * flag set, and if it does, writes the chunk.
- *
- * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
- * the chunks will be written if the WRITE routine is there and
- * information * is available in the COLORSPACE. (See
- * png_colorspace_sync_info in png.c for where the valid flags get set.)
- *
- * Under certain circumstances the colorspace can be invalidated without
- * syncing the info_struct 'valid' flags; this happens if libpng detects
- * an error and calls png_error while the color space is being set, yet
- * the application continues writing the PNG. So check the 'invalid'
- * flag here too.
- */
-#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
- /* Write unknown chunks first; PNG v3 establishes a precedence order
- * for colourspace chunks. It is certain therefore that new
- * colourspace chunks will have a precedence and very likely it will be
- * higher than all known so far. Writing the unknown chunks here is
- * most likely to present the chunks in the most convenient order.
- *
- * FUTURE: maybe write chunks in the order the app calls png_set_chnk
- * to give the app control.
- */
- write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+ /* The rest of these check to see if the valid field has the appropriate
+ * flag set, and if it does, writes the chunk.
+ *
+ * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
+ * the chunks will be written if the WRITE routine is there and information
+ * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c
+ * for where the valid flags get set.)
+ *
+ * Under certain circumstances the colorspace can be invalidated without
+ * syncing the info_struct 'valid' flags; this happens if libpng detects and
+ * error and calls png_error while the color space is being set, yet the
+ * application continues writing the PNG. So check the 'invalid' flag here
+ * too.
+ */
+#ifdef PNG_GAMMA_SUPPORTED
+# ifdef PNG_WRITE_gAMA_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) &&
+ (info_ptr->valid & PNG_INFO_gAMA))
+ png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
+# endif
#endif
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Write only one of sRGB or an ICC profile. If a profile was supplied
+ * and it matches one of the known sRGB ones issue a warning.
+ */
+# ifdef PNG_WRITE_iCCP_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->valid & PNG_INFO_iCCP))
+ {
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ png_app_warning(png_ptr,
+ "profile matches sRGB but writing iCCP instead");
+# endif
+
+ png_write_iCCP(png_ptr, info_ptr->iccp_name,
+ info_ptr->iccp_profile);
+ }
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ else
+# endif
+# endif
+
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->valid & PNG_INFO_sRGB))
+ png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
+# endif /* WRITE_sRGB */
+#endif /* COLORSPACE */
+
#ifdef PNG_WRITE_sBIT_SUPPORTED
- /* PNG v3: a streaming app will need to see this before cICP because
- * the information is helpful in handling HLG encoding (which is
- * natively 10 bits but gets expanded to 16 in PNG.)
- *
- * The app shouldn't care about the order ideally, but it might have
- * no choice. In PNG v3, apps are allowed to reject PNGs where the
- * APNG chunks are out of order so it behooves libpng to be nice here.
- */
- if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
- png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
#endif
- /* PNG v3: the July 2004 version of the TR introduced the concept of colour
- * space priority. As above it therefore behooves libpng to write the colour
- * space chunks in the priority order so that a streaming app need not buffer
- * them.
- *
- * PNG v3: Chunks mDCV and cLLI provide ancillary information for the
- * interpretation of the colourspace chunkgs but do not require support for
- * those chunks so are outside the "COLORSPACE" check but before the write of
- * the colourspace chunks themselves.
- */
-#ifdef PNG_WRITE_cLLI_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_cLLI) != 0)
- {
- png_write_cLLI_fixed(png_ptr, info_ptr->maxCLL, info_ptr->maxFALL);
- }
-#endif
-#ifdef PNG_WRITE_mDCV_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_mDCV) != 0)
- {
- png_write_mDCV_fixed(png_ptr,
- info_ptr->mastering_red_x, info_ptr->mastering_red_y,
- info_ptr->mastering_green_x, info_ptr->mastering_green_y,
- info_ptr->mastering_blue_x, info_ptr->mastering_blue_y,
- info_ptr->mastering_white_x, info_ptr->mastering_white_y,
- info_ptr->mastering_maxDL, info_ptr->mastering_minDL);
- }
+#ifdef PNG_COLORSPACE_SUPPORTED
+# ifdef PNG_WRITE_cHRM_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) &&
+ (info_ptr->valid & PNG_INFO_cHRM))
+ png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
+# endif
#endif
-# ifdef PNG_WRITE_cICP_SUPPORTED /* Priority 4 */
- if ((info_ptr->valid & PNG_INFO_cICP) != 0)
- {
- png_write_cICP(png_ptr,
- info_ptr->cicp_colour_primaries,
- info_ptr->cicp_transfer_function,
- info_ptr->cicp_matrix_coefficients,
- info_ptr->cicp_video_full_range_flag);
- }
-# endif
-
-# ifdef PNG_WRITE_iCCP_SUPPORTED /* Priority 3 */
- if ((info_ptr->valid & PNG_INFO_iCCP) != 0)
- {
- png_write_iCCP(png_ptr, info_ptr->iccp_name,
- info_ptr->iccp_profile, info_ptr->iccp_proflen);
- }
-# endif
-
-# ifdef PNG_WRITE_sRGB_SUPPORTED /* Priority 2 */
- if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
- png_write_sRGB(png_ptr, info_ptr->rendering_intent);
-# endif /* WRITE_sRGB */
-
-# ifdef PNG_WRITE_gAMA_SUPPORTED /* Priority 1 */
- if ((info_ptr->valid & PNG_INFO_gAMA) != 0)
- png_write_gAMA_fixed(png_ptr, info_ptr->gamma);
-# endif
-
-# ifdef PNG_WRITE_cHRM_SUPPORTED /* Also priority 1 */
- if ((info_ptr->valid & PNG_INFO_cHRM) != 0)
- png_write_cHRM_fixed(png_ptr, &info_ptr->cHRM);
-# endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+#endif
png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
}
@@ -233,7 +201,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
png_write_info_before_PLTE(png_ptr, info_ptr);
- if ((info_ptr->valid & PNG_INFO_PLTE) != 0)
+ if (info_ptr->valid & PNG_INFO_PLTE)
png_write_PLTE(png_ptr, info_ptr->palette,
(png_uint_32)info_ptr->num_palette);
@@ -241,20 +209,15 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
png_error(png_ptr, "Valid palette required for paletted images");
#ifdef PNG_WRITE_tRNS_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_tRNS) !=0)
+ if (info_ptr->valid & PNG_INFO_tRNS)
{
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
/* Invert the alpha channel (in tRNS) */
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 &&
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
- int j, jend;
-
- jend = info_ptr->num_trans;
- if (jend > PNG_MAX_PALETTE_LENGTH)
- jend = PNG_MAX_PALETTE_LENGTH;
-
- for (j = 0; jnum_trans; j++)
info_ptr->trans_alpha[j] =
(png_byte)(255 - info_ptr->trans_alpha[j]);
}
@@ -264,50 +227,42 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
}
#endif
#ifdef PNG_WRITE_bKGD_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_bKGD) != 0)
+ if (info_ptr->valid & PNG_INFO_bKGD)
png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
#endif
-#ifdef PNG_WRITE_eXIf_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
- {
- png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
- png_ptr->mode |= PNG_WROTE_eXIf;
- }
-#endif
-
#ifdef PNG_WRITE_hIST_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_hIST) != 0)
+ if (info_ptr->valid & PNG_INFO_hIST)
png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
#endif
#ifdef PNG_WRITE_oFFs_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_oFFs) != 0)
+ if (info_ptr->valid & PNG_INFO_oFFs)
png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
info_ptr->offset_unit_type);
#endif
#ifdef PNG_WRITE_pCAL_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_pCAL) != 0)
+ if (info_ptr->valid & PNG_INFO_pCAL)
png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
info_ptr->pcal_units, info_ptr->pcal_params);
#endif
#ifdef PNG_WRITE_sCAL_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_sCAL) != 0)
+ if (info_ptr->valid & PNG_INFO_sCAL)
png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
info_ptr->scal_s_width, info_ptr->scal_s_height);
#endif /* sCAL */
#ifdef PNG_WRITE_pHYs_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_pHYs) != 0)
+ if (info_ptr->valid & PNG_INFO_pHYs)
png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
#endif /* pHYs */
#ifdef PNG_WRITE_tIME_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_tIME) != 0)
+ if (info_ptr->valid & PNG_INFO_tIME)
{
png_write_tIME(png_ptr, &(info_ptr->mod_time));
png_ptr->mode |= PNG_WROTE_tIME;
@@ -315,7 +270,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
#endif /* tIME */
#ifdef PNG_WRITE_sPLT_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_sPLT) != 0)
+ if (info_ptr->valid & PNG_INFO_sPLT)
for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
#endif /* sPLT */
@@ -337,14 +292,11 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
info_ptr->text[i].lang,
info_ptr->text[i].lang_key,
info_ptr->text[i].text);
- /* Mark this chunk as written */
- if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- else
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
#else
- png_warning(png_ptr, "Unable to write international text");
+ png_warning(png_ptr, "Unable to write international text");
#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
}
/* If we want a compressed text chunk */
@@ -353,12 +305,13 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
#ifdef PNG_WRITE_zTXt_SUPPORTED
/* Write compressed chunk */
png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].compression);
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
#else
png_warning(png_ptr, "Unable to write compressed text");
#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
}
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
@@ -396,12 +349,11 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
if (png_ptr == NULL)
return;
- if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "No IDATs written into file");
#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
- if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
- png_ptr->num_palette_max >= png_ptr->num_palette)
+ if (png_ptr->num_palette_max > png_ptr->num_palette)
png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
#endif
@@ -413,8 +365,8 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
#endif
#ifdef PNG_WRITE_tIME_SUPPORTED
/* Check to see if user has supplied a time chunk */
- if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
- (png_ptr->mode & PNG_WROTE_tIME) == 0)
+ if ((info_ptr->valid & PNG_INFO_tIME) &&
+ !(png_ptr->mode & PNG_WROTE_tIME))
png_write_tIME(png_ptr, &(info_ptr->mod_time));
#endif
@@ -423,7 +375,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
for (i = 0; i < info_ptr->num_text; i++)
{
png_debug2(2, "Writing trailer text chunk %d, type %d", i,
- info_ptr->text[i].compression);
+ info_ptr->text[i].compression);
/* An internationalized chunk? */
if (info_ptr->text[i].compression > 0)
{
@@ -435,14 +387,11 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
info_ptr->text[i].lang,
info_ptr->text[i].lang_key,
info_ptr->text[i].text);
- /* Mark this chunk as written */
- if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
- else
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
#else
png_warning(png_ptr, "Unable to write international text");
#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
}
else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
@@ -450,12 +399,13 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_WRITE_zTXt_SUPPORTED
/* Write compressed chunk */
png_write_zTXt(png_ptr, info_ptr->text[i].key,
- info_ptr->text[i].text, info_ptr->text[i].compression);
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
#else
png_warning(png_ptr, "Unable to write compressed text");
#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
}
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
@@ -464,21 +414,15 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
/* Write uncompressed chunk */
png_write_tEXt(png_ptr, info_ptr->text[i].key,
info_ptr->text[i].text, 0);
- /* Mark this chunk as written */
- info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
#else
png_warning(png_ptr, "Unable to write uncompressed text");
#endif
+
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
}
}
#endif
-
-#ifdef PNG_WRITE_eXIf_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_eXIf) != 0 &&
- (png_ptr->mode & PNG_WROTE_eXIf) == 0)
- png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
-#endif
-
#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
#endif
@@ -488,7 +432,6 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
/* Write end of PNG file */
png_write_IEND(png_ptr);
-
/* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
* and restored again in libpng-1.2.30, may cause some applications that
* do not set png_ptr->output_flush_fn to crash. If your application
@@ -505,7 +448,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_CONVERT_tIME_SUPPORTED
void PNGAPI
-png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime)
+png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
{
png_debug(1, "in png_convert_from_struct_tm");
@@ -525,16 +468,6 @@ png_convert_from_time_t(png_timep ptime, time_t ttime)
png_debug(1, "in png_convert_from_time_t");
tbuf = gmtime(&ttime);
- if (tbuf == NULL)
- {
- /* TODO: add a safe function which takes a png_ptr argument and raises
- * a png_error if the ttime argument is invalid and the call to gmtime
- * fails as a consequence.
- */
- memset(ptime, 0, sizeof(*ptime));
- return;
- }
-
png_convert_from_struct_tm(ptime, tbuf);
}
#endif
@@ -542,12 +475,11 @@ png_convert_from_time_t(png_timep ptime, time_t ttime)
/* Initialize png_ptr structure, and allocate any memory needed */
PNG_FUNCTION(png_structp,PNGAPI
png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
- png_error_ptr error_fn, png_error_ptr warn_fn),
- PNG_ALLOCATED)
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
{
#ifndef PNG_USER_MEM_SUPPORTED
png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, NULL, NULL, NULL);
+ error_fn, warn_fn, NULL, NULL, NULL);
#else
return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
warn_fn, NULL, NULL, NULL);
@@ -557,56 +489,56 @@ png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
PNG_FUNCTION(png_structp,PNGAPI
png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
- png_malloc_ptr malloc_fn, png_free_ptr free_fn),
- PNG_ALLOCATED)
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
{
png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
- error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
-#endif /* USER_MEM */
- if (png_ptr != NULL)
- {
- /* Set the zlib control values to defaults; they can be overridden by the
- * application after the struct has been created.
- */
- png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
- /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
- * pngwutil.c defaults it according to whether or not filters will be
- * used, and ignores this setting.
- */
- png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
- png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
- png_ptr->zlib_mem_level = 8;
- png_ptr->zlib_window_bits = 15;
- png_ptr->zlib_method = 8;
+ /* Set the zlib control values to defaults; they can be overridden by the
+ * application after the struct has been created.
+ */
+ png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
+
+ /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
+ * pngwutil.c defaults it according to whether or not filters will be used,
+ * and ignores this setting.
+ */
+ png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_mem_level = 8;
+ png_ptr->zlib_window_bits = 15;
+ png_ptr->zlib_method = 8;
#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
- png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
- png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
- png_ptr->zlib_text_mem_level = 8;
- png_ptr->zlib_text_window_bits = 15;
- png_ptr->zlib_text_method = 8;
-#endif /* WRITE_COMPRESSED_TEXT */
+ png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_text_mem_level = 8;
+ png_ptr->zlib_text_window_bits = 15;
+ png_ptr->zlib_text_method = 8;
+#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
- /* This is a highly dubious configuration option; by default it is off,
- * but it may be appropriate for private builds that are testing
- * extensions not conformant to the current specification, or of
- * applications that must not fail to write at all costs!
- */
-#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
+ /* This is a highly dubious configuration option; by default it is off, but
+ * it may be appropriate for private builds that are testing extensions not
+ * conformant to the current specification, or of applications that must not
+ * fail to write at all costs!
+ */
+# ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
/* In stable builds only warn if an application error can be completely
* handled.
*/
- png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
-#endif
+# endif
- /* App warnings are warnings in release (or release candidate) builds but
- * are errors during development.
- */
-#if PNG_RELEASE_BUILD
+ /* App warnings are warnings in release (or release candidate) builds but
+ * are errors during development.
+ */
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
-#endif
+# endif
+ if (png_ptr != NULL)
+ {
/* TODO: delay this, it can be done in png_init_io() (if the app doesn't
* do it itself) avoiding setting the default function if it is not
* required.
@@ -676,71 +608,6 @@ png_write_image(png_structrp png_ptr, png_bytepp image)
}
}
-#ifdef PNG_MNG_FEATURES_SUPPORTED
-/* Performs intrapixel differencing */
-static void
-png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
-{
- png_debug(1, "in png_do_write_intrapixel");
-
- if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
- {
- int bytes_per_pixel;
- png_uint_32 row_width = row_info->width;
- if (row_info->bit_depth == 8)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 3;
-
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 4;
-
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- *(rp) = (png_byte)(*rp - *(rp + 1));
- *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1));
- }
- }
-
-#ifdef PNG_WRITE_16BIT_SUPPORTED
- else if (row_info->bit_depth == 16)
- {
- png_bytep rp;
- png_uint_32 i;
-
- if (row_info->color_type == PNG_COLOR_TYPE_RGB)
- bytes_per_pixel = 6;
-
- else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- bytes_per_pixel = 8;
-
- else
- return;
-
- for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
- {
- png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
- png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
- png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
- png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
- png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
- *(rp ) = (png_byte)(red >> 8);
- *(rp + 1) = (png_byte)red;
- *(rp + 4) = (png_byte)(blue >> 8);
- *(rp + 5) = (png_byte)blue;
- }
- }
-#endif /* WRITE_16BIT */
- }
-}
-#endif /* MNG_FEATURES */
-
/* Called by user to write a row of image data */
void PNGAPI
png_write_row(png_structrp png_ptr, png_const_bytep row)
@@ -748,54 +615,54 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
/* 1.5.6: moved from png_struct to be a local structure: */
png_row_info row_info;
- png_debug2(1, "in png_write_row (row %u, pass %d)",
- png_ptr->row_number, png_ptr->pass);
-
if (png_ptr == NULL)
return;
+ png_debug2(1, "in png_write_row (row %u, pass %d)",
+ png_ptr->row_number, png_ptr->pass);
+
/* Initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
/* Make sure we wrote the header info */
- if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
png_error(png_ptr,
"png_write_info was never called before png_write_row");
/* Check for transforms that have been set but were defined out */
#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
- if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
- if ((png_ptr->transformations & PNG_FILLER) != 0)
+ if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
defined(PNG_READ_PACKSWAP_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ if (png_ptr->transformations & PNG_PACKSWAP)
png_warning(png_ptr,
"PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
- if ((png_ptr->transformations & PNG_PACK) != 0)
+ if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
- if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
- if ((png_ptr->transformations & PNG_BGR) != 0)
+ if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
#endif
#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
- if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
#endif
@@ -804,13 +671,12 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* If interlaced and not interested in row, return */
- if (png_ptr->interlaced != 0 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0)
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{
switch (png_ptr->pass)
{
case 0:
- if ((png_ptr->row_number & 0x07) != 0)
+ if (png_ptr->row_number & 0x07)
{
png_write_finish_row(png_ptr);
return;
@@ -818,7 +684,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
break;
case 1:
- if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
{
png_write_finish_row(png_ptr);
return;
@@ -834,7 +700,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
break;
case 3:
- if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)
+ if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
{
png_write_finish_row(png_ptr);
return;
@@ -850,7 +716,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
break;
case 5:
- if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)
+ if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
{
png_write_finish_row(png_ptr);
return;
@@ -858,7 +724,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
break;
case 6:
- if ((png_ptr->row_number & 0x01) == 0)
+ if (!(png_ptr->row_number & 0x01))
{
png_write_finish_row(png_ptr);
return;
@@ -892,11 +758,11 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Handle interlacing */
if (png_ptr->interlaced && png_ptr->pass < 6 &&
- (png_ptr->transformations & PNG_INTERLACE) != 0)
+ (png_ptr->transformations & PNG_INTERLACE))
{
png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
/* This should always get caught above, but still ... */
- if (row_info.width == 0)
+ if (!(row_info.width))
{
png_write_finish_row(png_ptr);
return;
@@ -906,7 +772,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
/* Handle other transformations */
- if (png_ptr->transformations != 0)
+ if (png_ptr->transformations)
png_do_write_transformations(png_ptr, &row_info);
#endif
@@ -914,7 +780,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
* which is also the output depth.
*/
if (row_info.pixel_depth != png_ptr->pixel_depth ||
- row_info.pixel_depth != png_ptr->transformed_pixel_depth)
+ row_info.pixel_depth != png_ptr->transformed_pixel_depth)
png_error(png_ptr, "internal write transform logic error");
#ifdef PNG_MNG_FEATURES_SUPPORTED
@@ -927,7 +793,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
* 4. The filter_method is 64 and
* 5. The color_type is RGB or RGBA
*/
- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
{
/* Intrapixel differencing */
@@ -960,7 +826,7 @@ png_set_flush(png_structrp png_ptr, int nrows)
if (png_ptr == NULL)
return;
- png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
+ png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
}
/* Flush the current output buffers now */
@@ -980,7 +846,11 @@ png_write_flush(png_structrp png_ptr)
png_ptr->flush_rows = 0;
png_flush(png_ptr);
}
-#endif /* WRITE_FLUSH */
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
+#endif
/* Free any memory used in png_ptr struct without freeing the struct itself. */
static void
@@ -989,25 +859,29 @@ png_write_destroy(png_structrp png_ptr)
png_debug(1, "in png_write_destroy");
/* Free any memory zlib uses */
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
deflateEnd(&png_ptr->zstream);
/* Free our memory. png_free checks NULL for us. */
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_free(png_ptr, png_ptr->row_buf);
- png_ptr->row_buf = NULL;
#ifdef PNG_WRITE_FILTER_SUPPORTED
png_free(png_ptr, png_ptr->prev_row);
- png_free(png_ptr, png_ptr->try_row);
- png_free(png_ptr, png_ptr->tst_row);
- png_ptr->prev_row = NULL;
- png_ptr->try_row = NULL;
- png_ptr->tst_row = NULL;
+ png_free(png_ptr, png_ptr->sub_row);
+ png_free(png_ptr, png_ptr->up_row);
+ png_free(png_ptr, png_ptr->avg_row);
+ png_free(png_ptr, png_ptr->paeth_row);
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* Use this to save a little code space, it doesn't free the filter_costs */
+ png_reset_filter_heuristics(png_ptr);
+ png_free(png_ptr, png_ptr->filter_costs);
+ png_free(png_ptr, png_ptr->inv_filter_costs);
#endif
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
png_free(png_ptr, png_ptr->chunk_list);
- png_ptr->chunk_list = NULL;
#endif
/* The error handling and memory handling information is left intact at this
@@ -1053,7 +927,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
return;
#ifdef PNG_MNG_FEATURES_SUPPORTED
- if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(method == PNG_INTRAPIXEL_DIFFERENCING))
method = PNG_FILTER_TYPE_BASE;
@@ -1066,8 +940,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
case 5:
case 6:
case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
-#endif /* WRITE_FILTER */
- /* FALLTHROUGH */
+ /* FALL THROUGH */
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
case PNG_FILTER_VALUE_NONE:
png_ptr->do_filter = PNG_FILTER_NONE; break;
@@ -1089,88 +963,211 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
#else
default:
png_app_error(png_ptr, "Unknown row filter for method 0");
-#endif /* WRITE_FILTER */
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
}
-#ifdef PNG_WRITE_FILTER_SUPPORTED
/* If we have allocated the row_buf, this means we have already started
* with the image and we should have allocated all of the filter buffers
* that have been selected. If prev_row isn't already allocated, then
* it is too late to start using the filters that need it, since we
* will be missing the data in the previous row. If an application
* wants to start and stop using particular filters during compression,
- * it should start out with all of the filters, and then remove them
- * or add them back after the start of compression.
- *
- * NOTE: this is a nasty constraint on the code, because it means that the
- * prev_row buffer must be maintained even if there are currently no
- * 'prev_row' requiring filters active.
+ * it should start out with all of the filters, and then add and
+ * remove them after the start of compression.
*/
if (png_ptr->row_buf != NULL)
{
- int num_filters;
- png_alloc_size_t buf_size;
-
- /* Repeat the checks in png_write_start_row; 1 pixel high or wide
- * images cannot benefit from certain filters. If this isn't done here
- * the check below will fire on 1 pixel high images.
- */
- if (png_ptr->height == 1)
- filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
-
- if (png_ptr->width == 1)
- filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
-
- if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0
- && png_ptr->prev_row == NULL)
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
{
- /* This is the error case, however it is benign - the previous row
- * is not available so the filter can't be used. Just warn here.
- */
- png_app_warning(png_ptr,
- "png_set_filter: UP/AVG/PAETH cannot be added after start");
- filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
}
- num_filters = 0;
-
- if (filters & PNG_FILTER_SUB)
- num_filters++;
-
- if (filters & PNG_FILTER_UP)
- num_filters++;
-
- if (filters & PNG_FILTER_AVG)
- num_filters++;
-
- if (filters & PNG_FILTER_PAETH)
- num_filters++;
-
- /* Allocate needed row buffers if they have not already been
- * allocated.
- */
- buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth,
- png_ptr->width) + 1;
-
- if (png_ptr->try_row == NULL)
- png_ptr->try_row = png_voidcast(png_bytep,
- png_malloc(png_ptr, buf_size));
-
- if (num_filters > 1)
+ if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
{
- if (png_ptr->tst_row == NULL)
- png_ptr->tst_row = png_voidcast(png_bytep,
- png_malloc(png_ptr, buf_size));
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Up filter after starting");
+ png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+ ~PNG_FILTER_UP);
+ }
+
+ else
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
}
+
+ if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Average filter after starting");
+ png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+ ~PNG_FILTER_AVG);
+ }
+
+ else
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+ png_ptr->paeth_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Paeth filter after starting");
+ png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+ }
+
+ else
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+ if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ png_ptr->do_filter = PNG_FILTER_NONE;
}
- png_ptr->do_filter = (png_byte)filters;
-#endif
}
else
png_error(png_ptr, "Unknown custom filter method");
}
-#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline. While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */
+/* Convenience reset API. */
+static void
+png_reset_filter_heuristics(png_structrp png_ptr)
+{
+ /* Clear out any old values in the 'weights' - this must be done because if
+ * the app calls set_filter_heuristics multiple times with different
+ * 'num_weights' values we would otherwise potentially have wrong sized
+ * arrays.
+ */
+ png_ptr->num_prev_filters = 0;
+ png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+ if (png_ptr->prev_filters != NULL)
+ {
+ png_bytep old = png_ptr->prev_filters;
+ png_ptr->prev_filters = NULL;
+ png_free(png_ptr, old);
+ }
+ if (png_ptr->filter_weights != NULL)
+ {
+ png_uint_16p old = png_ptr->filter_weights;
+ png_ptr->filter_weights = NULL;
+ png_free(png_ptr, old);
+ }
+
+ if (png_ptr->inv_filter_weights != NULL)
+ {
+ png_uint_16p old = png_ptr->inv_filter_weights;
+ png_ptr->inv_filter_weights = NULL;
+ png_free(png_ptr, old);
+ }
+
+ /* Leave the filter_costs - this array is fixed size. */
+}
+
+static int
+png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+ int num_weights)
+{
+ if (png_ptr == NULL)
+ return 0;
+
+ /* Clear out the arrays */
+ png_reset_filter_heuristics(png_ptr);
+
+ /* Check arguments; the 'reset' function makes the correct settings for the
+ * unweighted case, but we must handle the weight case by initializing the
+ * arrays for the caller.
+ */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+
+ if (num_weights > 0)
+ {
+ png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_byte)) * num_weights));
+
+ /* To make sure that the weighting starts out fairly */
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->prev_filters[i] = 255;
+ }
+
+ png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+ png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ /* Safe to set this now */
+ png_ptr->num_prev_filters = (png_byte)num_weights;
+ }
+
+ /* If, in the future, there are other filter methods, this would
+ * need to be based on png_ptr->filter.
+ */
+ if (png_ptr->filter_costs == NULL)
+ {
+ png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+
+ png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+ }
+
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+
+ /* All the arrays are inited, safe to set this: */
+ png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
+
+ /* Return the 'ok' code. */
+ return 1;
+ }
+ else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
+ heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+ {
+ return 1;
+ }
+ else
+ {
+ png_warning(png_ptr, "Unknown filter heuristic method");
+ return 0;
+ }
+}
+
/* Provide floating and fixed point APIs */
#ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
@@ -1178,11 +1175,52 @@ png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
int num_weights, png_const_doublep filter_weights,
png_const_doublep filter_costs)
{
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(heuristic_method)
- PNG_UNUSED(num_weights)
- PNG_UNUSED(filter_weights)
- PNG_UNUSED(filter_costs)
+ png_debug(1, "in png_set_filter_heuristics");
+
+ /* The internal API allocates all the arrays and ensures that the elements of
+ * those arrays are set to the default value.
+ */
+ if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
+ return;
+
+ /* If using the weighted method copy in the weights. */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] <= 0.0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ else
+ {
+ png_ptr->inv_filter_weights[i] =
+ (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
+
+ png_ptr->filter_weights[i] =
+ (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
+
+ png_ptr->filter_costs[i] =
+ (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
+ }
+ }
}
#endif /* FLOATING_POINT */
@@ -1192,16 +1230,67 @@ png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
int num_weights, png_const_fixed_point_p filter_weights,
png_const_fixed_point_p filter_costs)
{
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(heuristic_method)
- PNG_UNUSED(num_weights)
- PNG_UNUSED(filter_weights)
- PNG_UNUSED(filter_costs)
+ png_debug(1, "in png_set_filter_heuristics_fixed");
+
+ /* The internal API allocates all the arrays and ensures that the elements of
+ * those arrays are set to the default value.
+ */
+ if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
+ return;
+
+ /* If using the weighted method copy in the weights. */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] <= 0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ else
+ {
+ png_ptr->inv_filter_weights[i] = (png_uint_16)
+ ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
+
+ png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
+ PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ if (filter_costs[i] >= PNG_FP_1)
+ {
+ png_uint_32 tmp;
+
+ /* Use a 32 bit unsigned temporary here because otherwise the
+ * intermediate value will be a 32 bit *signed* integer (ANSI rules)
+ * and this will get the wrong answer on division.
+ */
+ tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
+ tmp /= filter_costs[i];
+
+ png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
+
+ tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
+ tmp /= PNG_FP_1;
+
+ png_ptr->filter_costs[i] = (png_uint_16)tmp;
+ }
+ }
}
#endif /* FIXED_POINT */
-#endif /* WRITE_WEIGHTED_FILTER */
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
-#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
void PNGAPI
png_set_compression_level(png_structrp png_ptr, int level)
{
@@ -1244,13 +1333,11 @@ png_set_compression_strategy(png_structrp png_ptr, int strategy)
void PNGAPI
png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
{
- png_debug(1, "in png_set_compression_window_bits");
-
if (png_ptr == NULL)
return;
- /* Prior to 1.6.0 this would warn but then set the window_bits value. This
- * meant that negative window bits values could be selected that would cause
+ /* Prior to 1.6.0 this would warn but then set the window_bits value, this
+ * meant that negative window bits values could be selected which would cause
* libpng to write a non-standard PNG file with raw deflate or gzip
* compressed IDAT or ancillary chunks. Such files can be read and there is
* no warning on read, so this seems like a very bad idea.
@@ -1286,7 +1373,6 @@ png_set_compression_method(png_structrp png_ptr, int method)
png_ptr->zlib_method = method;
}
-#endif /* WRITE_CUSTOMIZE_COMPRESSION */
/* The following were added to libpng-1.5.4 */
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
@@ -1329,8 +1415,6 @@ png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
void PNGAPI
png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
{
- png_debug(1, "in png_set_text_compression_window_bits");
-
if (png_ptr == NULL)
return;
@@ -1362,14 +1446,12 @@ png_set_text_compression_method(png_structrp png_ptr, int method)
png_ptr->zlib_text_method = method;
}
-#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
/* end of API added to libpng-1.5.4 */
void PNGAPI
png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
{
- png_debug(1, "in png_set_write_status_fn");
-
if (png_ptr == NULL)
return;
@@ -1378,8 +1460,8 @@ png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
void PNGAPI
-png_set_write_user_transform_fn(png_structrp png_ptr,
- png_user_transform_ptr write_user_transform_fn)
+png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
{
png_debug(1, "in png_set_write_user_transform_fn");
@@ -1395,145 +1477,114 @@ png_set_write_user_transform_fn(png_structrp png_ptr,
#ifdef PNG_INFO_IMAGE_SUPPORTED
void PNGAPI
png_write_png(png_structrp png_ptr, png_inforp info_ptr,
- int transforms, png_voidp params)
+ int transforms, voidp params)
{
- png_debug(1, "in png_write_png");
-
if (png_ptr == NULL || info_ptr == NULL)
return;
- if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
- {
- png_app_error(png_ptr, "no rows for png_write_image to write");
- return;
- }
-
/* Write the file header information. */
png_write_info(png_ptr, info_ptr);
/* ------ these transformations don't touch the info structure ------- */
- /* Invert monochrome pixels */
- if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
#ifdef PNG_WRITE_INVERT_SUPPORTED
+ /* Invert monochrome pixels */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
png_set_invert_mono(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
#endif
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
/* Shift the pixels up to a legal bit depth and fill in
* as appropriate to correctly scale the image.
*/
- if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
- if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
- png_set_shift(png_ptr, &info_ptr->sig_bit);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && (info_ptr->valid & PNG_INFO_sBIT))
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
#endif
- /* Pack pixels into bytes */
- if ((transforms & PNG_TRANSFORM_PACKING) != 0)
#ifdef PNG_WRITE_PACK_SUPPORTED
- png_set_packing(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
+ /* Pack pixels into bytes */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
#endif
- /* Swap location of alpha bytes from ARGB to RGBA */
- if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ /* Swap location of alpha bytes from ARGB to RGBA */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
png_set_swap_alpha(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
#endif
- /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
- * RGB, note that the code expects the input color type to be G or RGB; no
- * alpha channel.
- */
- if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|
- PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)
- {
#ifdef PNG_WRITE_FILLER_SUPPORTED
- if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)
- {
- if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
- png_app_error(png_ptr,
- "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
+ /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
- /* Continue if ignored - this is the pre-1.6.10 behavior */
- png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
- }
-
- else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
- png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
+ else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
#endif
- }
- /* Flip BGR pixels to RGB */
- if ((transforms & PNG_TRANSFORM_BGR) != 0)
#ifdef PNG_WRITE_BGR_SUPPORTED
+ /* Flip BGR pixels to RGB */
+ if (transforms & PNG_TRANSFORM_BGR)
png_set_bgr(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
#endif
- /* Swap bytes of 16-bit files to most significant byte first */
- if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
#ifdef PNG_WRITE_SWAP_SUPPORTED
+ /* Swap bytes of 16-bit files to most significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
png_set_swap(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
#endif
- /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */
- if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ /* Swap bits of 1, 2, 4 bit packed pixel formats */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
png_set_packswap(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
#endif
- /* Invert the alpha channel from opacity to transparency */
- if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
png_set_invert_alpha(png_ptr);
-#else
- png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
#endif
/* ----------------------- end of transformations ------------------- */
/* Write the bits */
- png_write_image(png_ptr, info_ptr->row_pointers);
+ if (info_ptr->valid & PNG_INFO_IDAT)
+ png_write_image(png_ptr, info_ptr->row_pointers);
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
+ PNG_UNUSED(transforms) /* Quiet compiler warnings */
PNG_UNUSED(params)
}
#endif
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
/* Initialize the write structure - general purpose utility. */
static int
-png_image_write_init(png_imagep image)
+// 4j studios: callback support
+png_image_write_init(png_imagep image, /*begin 4j change*/ png_rw_ptr write_fn, png_flush_ptr flush_fn /*end 4j change*/)
{
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
- png_safe_error, png_safe_warning);
+ png_safe_error, png_safe_warning);
if (png_ptr != NULL)
{
png_infop info_ptr = png_create_info_struct(png_ptr);
+ /*begin 4j change*/
+ if (write_fn != NULL)
+ png_set_write_fn(png_ptr, NULL, write_fn, flush_fn);
+ /*end 4j change*/
+
if (info_ptr != NULL)
{
png_controlp control = png_voidcast(png_controlp,
- png_malloc_warn(png_ptr, (sizeof *control)));
+ png_malloc_warn(png_ptr, (sizeof *control)));
if (control != NULL)
{
@@ -1560,22 +1611,16 @@ png_image_write_init(png_imagep image)
/* Arguments to png_image_write_main: */
typedef struct
{
- /* Arguments */
- png_imagep image;
+ /* Arguments: */
+ png_imagep image;
png_const_voidp buffer;
- png_int_32 row_stride;
+ png_int_32 row_stride;
png_const_voidp colormap;
- int convert_to_8bit;
-
- /* Instance variables */
+ int convert_to_8bit;
+ /* Local variables: */
png_const_voidp first_row;
- png_voidp local_row;
- ptrdiff_t row_step;
-
- /* Byte count for memory writing */
- png_bytep memory;
- png_alloc_size_t memory_bytes; /* not used for STDIO */
- png_alloc_size_t output_bytes; /* running total */
+ ptrdiff_t row_bytes;
+ png_voidp local_row;
} png_image_write_control;
/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
@@ -1586,33 +1631,29 @@ static int
png_write_image_16bit(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
- display->first_row);
+ display->first_row);
png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
png_uint_16p row_end;
- unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
- 3 : 1;
+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
int aindex = 0;
png_uint_32 y = image->height;
- if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (image->format & PNG_FORMAT_FLAG_ALPHA)
{
-# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
- if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ if (image->format & PNG_FORMAT_FLAG_AFIRST)
{
aindex = -1;
++input_row; /* To point to the first component */
++output_row;
}
- else
- aindex = (int)channels;
-# else
- aindex = (int)channels;
-# endif
+
+ else
+ aindex = channels;
}
else
@@ -1624,14 +1665,14 @@ png_write_image_16bit(png_voidp argument)
*/
row_end = output_row + image->width * (channels+1);
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_const_uint_16p in_ptr = input_row;
png_uint_16p out_ptr = output_row;
while (out_ptr < row_end)
{
- png_uint_16 alpha = in_ptr[aindex];
+ const png_uint_16 alpha = in_ptr[aindex];
png_uint_32 reciprocal = 0;
int c;
@@ -1645,7 +1686,7 @@ png_write_image_16bit(png_voidp argument)
if (alpha > 0 && alpha < 65535)
reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
- c = (int)channels;
+ c = channels;
do /* always at least one channel */
{
png_uint_16 component = *in_ptr++;
@@ -1680,7 +1721,7 @@ png_write_image_16bit(png_voidp argument)
}
png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
- input_row += display->row_step / 2;
+ input_row += display->row_bytes/(sizeof (png_uint_16));
}
return 1;
@@ -1694,11 +1735,11 @@ png_write_image_16bit(png_voidp argument)
* calculation can be done to 15 bits of accuracy; however, the output needs to
* be scaled in the range 0..255*65535, so include that scaling here.
*/
-# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha))
+#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
- png_uint_32 reciprocal/*from the above macro*/)
+ png_uint_32 reciprocal/*from the above macro*/)
{
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
* is represented as some other value there is more likely to be a
@@ -1745,24 +1786,22 @@ static int
png_write_image_8bit(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
- display->first_row);
+ display->first_row);
png_bytep output_row = png_voidcast(png_bytep, display->local_row);
png_uint_32 y = image->height;
- unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
- 3 : 1;
+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
- if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (image->format & PNG_FORMAT_FLAG_ALPHA)
{
png_bytep row_end;
int aindex;
-# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
- if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ if (image->format & PNG_FORMAT_FLAG_AFIRST)
{
aindex = -1;
++input_row; /* To point to the first component */
@@ -1770,13 +1809,12 @@ png_write_image_8bit(png_voidp argument)
}
else
-# endif
- aindex = (int)channels;
+ aindex = channels;
/* Use row_end in place of a loop counter: */
row_end = output_row + image->width * (channels+1);
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row;
@@ -1794,7 +1832,7 @@ png_write_image_8bit(png_voidp argument)
if (alphabyte > 0 && alphabyte < 255)
reciprocal = UNP_RECIPROCAL(alpha);
- c = (int)channels;
+ c = channels;
do /* always at least one channel */
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
while (--c > 0);
@@ -1805,8 +1843,8 @@ png_write_image_8bit(png_voidp argument)
} /* while out_ptr < row_end */
png_write_row(png_ptr, png_voidcast(png_const_bytep,
- display->local_row));
- input_row += display->row_step / 2;
+ display->local_row));
+ input_row += display->row_bytes/(sizeof (png_uint_16));
} /* while y */
}
@@ -1817,7 +1855,7 @@ png_write_image_8bit(png_voidp argument)
*/
png_bytep row_end = output_row + image->width * channels;
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row;
@@ -1831,7 +1869,7 @@ png_write_image_8bit(png_voidp argument)
}
png_write_row(png_ptr, output_row);
- input_row += display->row_step / 2;
+ input_row += display->row_bytes/(sizeof (png_uint_16));
}
}
@@ -1841,28 +1879,27 @@ png_write_image_8bit(png_voidp argument)
static void
png_image_set_PLTE(png_image_write_control *display)
{
- png_imagep image = display->image;
+ const png_imagep image = display->image;
const void *cmap = display->colormap;
- int entries = image->colormap_entries > 256 ? 256 :
- (int)image->colormap_entries;
+ const int entries = image->colormap_entries > 256 ? 256 :
+ (int)image->colormap_entries;
/* NOTE: the caller must check for cmap != NULL and entries != 0 */
- png_uint_32 format = image->format;
- unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+ const png_uint_32 format = image->format;
+ const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
-# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
- defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
- int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
- (format & PNG_FORMAT_FLAG_ALPHA) != 0;
-# else
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+ (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+# else
# define afirst 0
-# endif
+# endif
-# ifdef PNG_FORMAT_BGR_SUPPORTED
- int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
-# else
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
+# else
# define bgr 0
-# endif
+# endif
int i, num_trans;
png_color palette[256];
@@ -1876,22 +1913,22 @@ png_image_set_PLTE(png_image_write_control *display)
/* This gets automatically converted to sRGB with reversal of the
* pre-multiplication if the color-map has an alpha channel.
*/
- if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
+ if (format & PNG_FORMAT_FLAG_LINEAR)
{
png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
- entry += (unsigned int)i * channels;
+ entry += i * channels;
- if ((channels & 1) != 0) /* no alpha */
+ if (channels & 1) /* no alpha */
{
if (channels >= 3) /* RGB */
{
palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
- entry[(2 ^ bgr)]);
+ entry[(2 ^ bgr)]);
palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
- entry[1]);
+ entry[1]);
palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
- entry[bgr]);
+ entry[bgr]);
}
else /* Gray */
@@ -1919,16 +1956,16 @@ png_image_set_PLTE(png_image_write_control *display)
if (channels >= 3) /* RGB */
{
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
- alpha, reciprocal);
+ alpha, reciprocal);
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
- reciprocal);
+ reciprocal);
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
- reciprocal);
+ reciprocal);
}
else /* gray */
palette[i].blue = palette[i].red = palette[i].green =
- png_unpremultiply(entry[afirst], alpha, reciprocal);
+ png_unpremultiply(entry[afirst], alpha, reciprocal);
}
}
@@ -1936,7 +1973,7 @@ png_image_set_PLTE(png_image_write_control *display)
{
png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
- entry += (unsigned int)i * channels;
+ entry += i * channels;
switch (channels)
{
@@ -1944,7 +1981,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[afirst ? 0 : 3];
if (tRNS[i] < 255)
num_trans = i+1;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case 3:
palette[i].blue = entry[afirst + (2 ^ bgr)];
palette[i].green = entry[afirst + 1];
@@ -1955,7 +1992,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[1 ^ afirst];
if (tRNS[i] < 255)
num_trans = i+1;
- /* FALLTHROUGH */
+ /* FALL THROUGH */
case 1:
palette[i].blue = palette[i].red = palette[i].green =
entry[afirst];
@@ -1967,108 +2004,73 @@ png_image_set_PLTE(png_image_write_control *display)
}
}
-# ifdef afirst
+# ifdef afirst
# undef afirst
-# endif
-# ifdef bgr
+# endif
+# ifdef bgr
# undef bgr
-# endif
+# endif
png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
- entries);
+ entries);
if (num_trans > 0)
png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
- num_trans, NULL);
+ num_trans, NULL);
- image->colormap_entries = (png_uint_32)entries;
+ image->colormap_entries = entries;
}
static int
png_image_write_main(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
- argument);
+ argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
png_uint_32 format = image->format;
- /* The following four ints are actually booleans */
- int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
- int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
- int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
- int write_16bit = linear && (display->convert_to_8bit == 0);
+ int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
+ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
+ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+ int write_16bit = linear && !colormap && !display->convert_to_8bit;
-# ifdef PNG_BENIGN_ERRORS_SUPPORTED
+# ifdef PNG_BENIGN_ERRORS_SUPPORTED
/* Make sure we error out on any bad situation */
png_set_benign_errors(png_ptr, 0/*error*/);
-# endif
+# endif
- /* Default the 'row_stride' parameter if required, also check the row stride
- * and total image size to ensure that they are within the system limits.
- */
- {
- unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
-
- if (image->width <= 0x7fffffffU/channels) /* no overflow */
- {
- png_uint_32 check;
- png_uint_32 png_row_stride = image->width * channels;
-
- if (display->row_stride == 0)
- display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
-
- if (display->row_stride < 0)
- check = (png_uint_32)(-display->row_stride);
-
- else
- check = (png_uint_32)display->row_stride;
-
- if (check >= png_row_stride)
- {
- /* Now check for overflow of the image buffer calculation; this
- * limits the whole image size to 32 bits for API compatibility with
- * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
- */
- if (image->height > 0xffffffffU/png_row_stride)
- png_error(image->opaque->png_ptr, "memory image too large");
- }
-
- else
- png_error(image->opaque->png_ptr, "supplied row stride too small");
- }
-
- else
- png_error(image->opaque->png_ptr, "image row stride too large");
- }
+ /* Default the 'row_stride' parameter if required. */
+ if (display->row_stride == 0)
+ display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
/* Set the required transforms then write the rows in the correct order. */
- if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+ if (format & PNG_FORMAT_FLAG_COLORMAP)
{
if (display->colormap != NULL && image->colormap_entries > 0)
{
png_uint_32 entries = image->colormap_entries;
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
- entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
- PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_image_set_PLTE(display);
}
else
png_error(image->opaque->png_ptr,
- "no color-map for color-mapped image");
+ "no color-map for color-mapped image");
}
else
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
- write_16bit ? 16 : 8,
- ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
- ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ write_16bit ? 16 : 8,
+ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* Counter-intuitively the data transformations must be called *after*
* png_write_info, not before as in the read code, but the 'set' functions
@@ -2076,22 +2078,22 @@ png_image_write_main(png_voidp argument)
* write an interlaced image.
*/
- if (write_16bit != 0)
+ if (write_16bit)
{
/* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
- if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+ if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
png_set_cHRM_fixed(png_ptr, info_ptr,
- /* color x y */
- /* white */ 31270, 32900,
- /* red */ 64000, 33000,
- /* green */ 30000, 60000,
- /* blue */ 15000, 6000
+ /* color x y */
+ /* white */ 31270, 32900,
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000
);
}
- else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+ else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
/* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
@@ -2106,38 +2108,38 @@ png_image_write_main(png_voidp argument)
/* Now set up the data transformations (*after* the header is written),
* remove the handled transformations from the 'format' flags for checking.
*
- * First check for a little endian system if writing 16-bit files.
+ * First check for a little endian system if writing 16 bit files.
*/
- if (write_16bit != 0)
+ if (write_16bit)
{
- png_uint_16 le = 0x0001;
+ PNG_CONST png_uint_16 le = 0x0001;
- if ((*(png_const_bytep) & le) != 0)
+ if (*(png_const_bytep)&le)
png_set_swap(png_ptr);
}
-# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
- if ((format & PNG_FORMAT_FLAG_BGR) != 0)
+# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_BGR)
{
- if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)
+ if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0)
png_set_bgr(png_ptr);
format &= ~PNG_FORMAT_FLAG_BGR;
}
-# endif
+# endif
-# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
- if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_AFIRST)
{
- if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
png_set_swap_alpha(png_ptr);
format &= ~PNG_FORMAT_FLAG_AFIRST;
}
-# endif
+# endif
/* If there are 16 or fewer color-map entries we wrote a lower bit depth
* above, but the application data is still byte packed.
*/
- if (colormap != 0 && image->colormap_entries <= 16)
+ if (colormap && image->colormap_entries <= 16)
png_set_packing(png_ptr);
/* That should have handled all (both) the transforms. */
@@ -2147,16 +2149,16 @@ png_image_write_main(png_voidp argument)
{
png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
- ptrdiff_t row_step = display->row_stride;
+ ptrdiff_t row_bytes = display->row_stride;
- if (linear != 0)
- row_step *= 2;
+ if (linear)
+ row_bytes *= (sizeof (png_uint_16));
- if (row_step < 0)
- row += (image->height-1) * (-row_step);
+ if (row_bytes < 0)
+ row += (image->height-1) * (-row_bytes);
display->first_row = row;
- display->row_step = row_step;
+ display->row_bytes = row_bytes;
}
/* Apply 'fast' options if the flag is set. */
@@ -2168,23 +2170,21 @@ png_image_write_main(png_voidp argument)
* it about 50 times. The speed-up in pngstest was about 10-20% of the
* total (user) time on a heavily loaded system.
*/
-# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
png_set_compression_level(png_ptr, 3);
-# endif
}
/* Check for the cases that currently require a pre-transform on the row
* before it is written. This only applies when the input is 16-bit and
* either there is an alpha channel or it is converted to 8-bit.
*/
- if (linear != 0 && (alpha != 0 || display->convert_to_8bit != 0))
+ if ((linear && alpha) || (!colormap && display->convert_to_8bit))
{
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
- png_get_rowbytes(png_ptr, info_ptr)));
+ png_get_rowbytes(png_ptr, info_ptr)));
int result;
display->local_row = row;
- if (write_16bit != 0)
+ if (write_16bit)
result = png_safe_execute(image, png_write_image_16bit, display);
else
result = png_safe_execute(image, png_write_image_8bit, display);
@@ -2193,7 +2193,7 @@ png_image_write_main(png_voidp argument)
png_free(png_ptr, row);
/* Skip the 'write_end' on error: */
- if (result == 0)
+ if (!result)
return 0;
}
@@ -2203,13 +2203,13 @@ png_image_write_main(png_voidp argument)
else
{
png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
- ptrdiff_t row_step = display->row_step;
+ ptrdiff_t row_bytes = display->row_bytes;
png_uint_32 y = image->height;
- for (; y > 0; --y)
+ while (y-- > 0)
{
png_write_row(png_ptr, row);
- row += row_step;
+ row += row_bytes;
}
}
@@ -2217,131 +2217,20 @@ png_image_write_main(png_voidp argument)
return 1;
}
-
-static void (PNGCBAPI
-image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size)
-{
- png_image_write_control *display = png_voidcast(png_image_write_control*,
- png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
- png_alloc_size_t ob = display->output_bytes;
-
- /* Check for overflow; this should never happen: */
- if (size <= ((png_alloc_size_t)-1) - ob)
- {
- /* I don't think libpng ever does this, but just in case: */
- if (size > 0)
- {
- if (display->memory_bytes >= ob+size) /* writing */
- memcpy(display->memory+ob, data, size);
-
- /* Always update the size: */
- display->output_bytes = ob+size;
- }
- }
-
- else
- png_error(png_ptr, "png_image_write_to_memory: PNG too big");
-}
-
-static void (PNGCBAPI
-image_memory_flush)(png_structp png_ptr)
-{
- PNG_UNUSED(png_ptr)
-}
-
-static int
-png_image_write_memory(png_voidp argument)
-{
- png_image_write_control *display = png_voidcast(png_image_write_control*,
- argument);
-
- /* The rest of the memory-specific init and write_main in an error protected
- * environment. This case needs to use callbacks for the write operations
- * since libpng has no built in support for writing to memory.
- */
- png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
- image_memory_write, image_memory_flush);
-
- return png_image_write_main(display);
-}
-
-int PNGAPI
-png_image_write_to_memory(png_imagep image, void *memory,
- png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
- const void *buffer, png_int_32 row_stride, const void *colormap)
-{
- /* Write the image to the given buffer, or count the bytes if it is NULL */
- if (image != NULL && image->version == PNG_IMAGE_VERSION)
- {
- if (memory_bytes != NULL && buffer != NULL)
- {
- /* This is to give the caller an easier error detection in the NULL
- * case and guard against uninitialized variable problems:
- */
- if (memory == NULL)
- *memory_bytes = 0;
-
- if (png_image_write_init(image) != 0)
- {
- png_image_write_control display;
- int result;
-
- memset(&display, 0, (sizeof display));
- display.image = image;
- display.buffer = buffer;
- display.row_stride = row_stride;
- display.colormap = colormap;
- display.convert_to_8bit = convert_to_8bit;
- display.memory = png_voidcast(png_bytep, memory);
- display.memory_bytes = *memory_bytes;
- display.output_bytes = 0;
-
- result = png_safe_execute(image, png_image_write_memory, &display);
- png_image_free(image);
-
- /* write_memory returns true even if we ran out of buffer. */
- if (result)
- {
- /* On out-of-buffer this function returns '0' but still updates
- * memory_bytes:
- */
- if (memory != NULL && display.output_bytes > *memory_bytes)
- result = 0;
-
- *memory_bytes = display.output_bytes;
- }
-
- return result;
- }
-
- else
- return 0;
- }
-
- else
- return png_image_error(image,
- "png_image_write_to_memory: invalid argument");
- }
-
- else if (image != NULL)
- return png_image_error(image,
- "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
-
- else
- return 0;
-}
-
-#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
int PNGAPI
+// 4j studios: callback support
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
- const void *buffer, png_int_32 row_stride, const void *colormap)
+ const void *buffer, png_int_32 row_stride, const void *colormap,
+ /*begin 4j change*/ png_rw_ptr write_fn, png_flush_ptr flush_fn /*end 4j change*/)
{
- /* Write the image to the given FILE object. */
+ /* Write the image to the given (FILE*). */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- if (file != NULL && buffer != NULL)
- {
- if (png_image_write_init(image) != 0)
+ // begin 4j change: allow null file, callback support
+ //if (file != NULL)
+ //{
+ //if (png_image_write_init(image))
+ if (png_image_write_init(image, write_fn, flush_fn))
{
png_image_write_control display;
int result;
@@ -2366,16 +2255,16 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
else
return 0;
- }
+ //}
- else
- return png_image_error(image,
- "png_image_write_to_stdio: invalid argument");
+ //else
+ //return png_image_error(image,
+ //"png_image_write_to_stdio: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
else
return 0;
@@ -2383,20 +2272,20 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
int PNGAPI
png_image_write_to_file(png_imagep image, const char *file_name,
- int convert_to_8bit, const void *buffer, png_int_32 row_stride,
- const void *colormap)
+ int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap)
{
/* Write the image to the named file. */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
- if (file_name != NULL && buffer != NULL)
+ if (file_name != NULL)
{
FILE *fp = fopen(file_name, "wb");
if (fp != NULL)
{
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
- row_stride, colormap) != 0)
+ row_stride, colormap /*begin 4j change*/, NULL, NULL /*end 4j change*/))
{
int error; /* from fflush/fclose */
@@ -2437,16 +2326,16 @@ png_image_write_to_file(png_imagep image, const char *file_name,
else
return png_image_error(image,
- "png_image_write_to_file: invalid argument");
+ "png_image_write_to_file: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
- "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
else
return 0;
}
-#endif /* SIMPLIFIED_WRITE_STDIO */
+#endif /* PNG_STDIO_SUPPORTED */
#endif /* SIMPLIFIED_WRITE */
-#endif /* WRITE */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngwtran.c b/Windows_Libs/Dev/Render/libpng/pngwtran.c
index a208470..98703f8 100644
--- a/Windows_Libs/Dev/Render/libpng/pngwtran.c
+++ b/Windows_Libs/Dev/Render/libpng/pngwtran.c
@@ -1,9 +1,10 @@
+
/* pngwtran.c - transforms the data in a row for PNG writers
*
- * Copyright (c) 2018 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@@ -13,14 +14,90 @@
#include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
+
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_write_transformations");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ if (png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* User write transform
+ function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_pack(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_shift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+}
#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* row_info bit depth should be 8 (one pixel per byte). The channels
* should be 1 (this only happens on grayscale and paletted images).
*/
-static void
+void /* PRIVATE */
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_debug(1, "in png_do_pack");
@@ -70,8 +147,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
case 2:
{
png_bytep sp, dp;
- unsigned int shift;
- int v;
+ int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
@@ -110,8 +186,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
case 4:
{
png_bytep sp, dp;
- unsigned int shift;
- int v;
+ int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
@@ -167,7 +242,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
* would pass 3 as bit_depth, and this routine would translate the
* data to 0 to 15.
*/
-static void
+void /* PRIVATE */
png_do_shift(png_row_infop row_info, png_bytep row,
png_const_color_8p bit_depth)
{
@@ -176,9 +251,9 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
- unsigned int channels = 0;
+ int channels = 0;
- if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift_start[channels] = row_info->bit_depth - bit_depth->red;
shift_dec[channels] = bit_depth->red;
@@ -200,7 +275,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
channels++;
}
- if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
shift_dec[channels] = bit_depth->alpha;
@@ -211,9 +286,9 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->bit_depth < 8)
{
png_bytep bp = row;
- size_t i;
+ png_size_t i;
unsigned int mask;
- size_t row_bytes = row_info->rowbytes;
+ png_size_t row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55;
@@ -253,7 +328,8 @@ png_do_shift(png_row_infop row_info, png_bytep row,
for (i = 0; i < istop; i++, bp++)
{
- unsigned int c = i%channels;
+
+ const unsigned int c = i%channels;
int j;
unsigned int v, out;
@@ -281,7 +357,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
for (bp = row, i = 0; i < istop; i++)
{
- unsigned int c = i%channels;
+ const unsigned int c = i%channels;
int j;
unsigned int value, v;
@@ -305,7 +381,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
-static void
+void /* PRIVATE */
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_swap_alpha");
@@ -353,7 +429,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save[1];
}
}
-#endif /* WRITE_16BIT */
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
@@ -392,14 +468,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = save[1];
}
}
-#endif /* WRITE_16BIT */
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
}
}
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
-static void
+void /* PRIVATE */
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_invert_alpha");
@@ -422,7 +498,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*(dp++) = *(sp++);
*/
sp+=3; dp = sp;
- *dp = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
}
}
@@ -446,10 +522,10 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*/
sp+=6; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
- *dp = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
}
}
-#endif /* WRITE_16BIT */
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
@@ -484,91 +560,78 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
*/
sp+=2; dp = sp;
*(dp++) = (png_byte)(255 - *(sp++));
- *dp = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
}
}
-#endif /* WRITE_16BIT */
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
}
}
}
#endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
-/* Transform the data according to the user's wishes. The order of
- * transformations is significant.
- */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
void /* PRIVATE */
-png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
{
- png_debug(1, "in png_do_write_transformations");
+ png_debug(1, "in png_do_write_intrapixel");
- if (png_ptr == NULL)
- return;
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
-#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
- if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
- if (png_ptr->write_user_transform_fn != NULL)
- (*(png_ptr->write_user_transform_fn)) /* User write transform
- function */
- (png_ptr, /* png_ptr */
- row_info, /* row_info: */
- /* png_uint_32 width; width of row */
- /* size_t rowbytes; number of bytes in row */
- /* png_byte color_type; color type of pixels */
- /* png_byte bit_depth; bit depth of samples */
- /* png_byte channels; number of channels (1-4) */
- /* png_byte pixel_depth; bits per pixel (depth*channels) */
- png_ptr->row_buf + 1); /* start of pixel data for row */
-#endif
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
-#ifdef PNG_WRITE_FILLER_SUPPORTED
- if ((png_ptr->transformations & PNG_FILLER) != 0)
- png_do_strip_channel(row_info, png_ptr->row_buf + 1,
- !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
-#endif
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
-#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
- if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
- png_do_packswap(row_info, png_ptr->row_buf + 1);
-#endif
+ else
+ return;
-#ifdef PNG_WRITE_PACK_SUPPORTED
- if ((png_ptr->transformations & PNG_PACK) != 0)
- png_do_pack(row_info, png_ptr->row_buf + 1,
- (png_uint_32)png_ptr->bit_depth);
-#endif
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff);
+ *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+ }
+ }
-#ifdef PNG_WRITE_SWAP_SUPPORTED
-# ifdef PNG_16BIT_SUPPORTED
- if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
- png_do_swap(row_info, png_ptr->row_buf + 1);
-# endif
-#endif
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
-#ifdef PNG_WRITE_SHIFT_SUPPORTED
- if ((png_ptr->transformations & PNG_SHIFT) != 0)
- png_do_shift(row_info, png_ptr->row_buf + 1,
- &(png_ptr->shift));
-#endif
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
-#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
- png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
-#endif
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
-#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
- if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
- png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
-#endif
+ else
+ return;
-#ifdef PNG_WRITE_BGR_SUPPORTED
- if ((png_ptr->transformations & PNG_BGR) != 0)
- png_do_bgr(row_info, png_ptr->row_buf + 1);
-#endif
-
-#ifdef PNG_WRITE_INVERT_SUPPORTED
- if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
- png_do_invert(row_info, png_ptr->row_buf + 1);
-#endif
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp + 1) = (png_byte)(red & 0xff);
+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp + 5) = (png_byte)(blue & 0xff);
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
}
-#endif /* WRITE_TRANSFORMS */
-#endif /* WRITE */
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/libpng/pngwutil.c b/Windows_Libs/Dev/Render/libpng/pngwutil.c
index b4b845a..49e6a2d 100644
--- a/Windows_Libs/Dev/Render/libpng/pngwutil.c
+++ b/Windows_Libs/Dev/Render/libpng/pngwutil.c
@@ -1,37 +1,20 @@
+
/* pngwutil.c - utilities to write a PNG file
*
- * Copyright (c) 2018-2025 Cosmin Truta
- * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
- * Copyright (c) 1996-1997 Andreas Dilger
- * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
- *
- * This file contains routines that are only called from within
- * libpng itself during the course of writing an image.
*/
#include "pngpriv.h"
#ifdef PNG_WRITE_SUPPORTED
-#ifdef PNG_WRITE_INTERLACING_SUPPORTED
-/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
-
-/* Start of interlace block */
-static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
-/* Offset to next interlace block */
-static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-/* Start of interlace block in the y direction */
-static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
-/* Offset to next interlace block in the y direction */
-static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
-
-/* TODO: Move these arrays to a common utility module to avoid duplication. */
-#endif
-
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
/* Place a 32-bit number into a buffer in PNG byte order. We work
* with unsigned numbers for convenience, although one supported
@@ -40,10 +23,10 @@ static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
- buf[0] = (png_byte)((i >> 24) & 0xffU);
- buf[1] = (png_byte)((i >> 16) & 0xffU);
- buf[2] = (png_byte)((i >> 8) & 0xffU);
- buf[3] = (png_byte)( i & 0xffU);
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
}
/* Place a 16-bit number into a buffer in PNG byte order.
@@ -53,8 +36,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
- buf[0] = (png_byte)((i >> 8) & 0xffU);
- buf[1] = (png_byte)( i & 0xffU);
+ buf[0] = (png_byte)((i >> 8) & 0xff);
+ buf[1] = (png_byte)(i & 0xff);
}
#endif
@@ -76,7 +59,7 @@ png_write_sig(png_structrp png_ptr)
/* Write the rest of the 8 byte signature */
png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
- (size_t)(8 - png_ptr->sig_bytes));
+ (png_size_t)(8 - png_ptr->sig_bytes));
if (png_ptr->sig_bytes < 3)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
@@ -141,7 +124,8 @@ png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
* given to png_write_chunk_header().
*/
void PNGAPI
-png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length)
+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
+ png_size_t length)
{
/* Write the data, and run the CRC over it */
if (png_ptr == NULL)
@@ -152,7 +136,7 @@ png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length)
png_write_data(png_ptr, data, length);
/* Update the CRC after writing the data,
- * in case the user I/O routine alters it.
+ * in case that the user I/O routine alters it.
*/
png_calculate_crc(png_ptr, data, length);
}
@@ -176,7 +160,7 @@ png_write_chunk_end(png_structrp png_ptr)
/* Write the crc in a single operation */
png_save_uint_32(buf, png_ptr->crc);
- png_write_data(png_ptr, buf, 4);
+ png_write_data(png_ptr, buf, (png_size_t)4);
}
/* Write a PNG chunk all at once. The type is an array of ASCII characters
@@ -190,14 +174,14 @@ png_write_chunk_end(png_structrp png_ptr)
*/
static void
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
- png_const_bytep data, size_t length)
+ png_const_bytep data, png_size_t length)
{
if (png_ptr == NULL)
return;
- /* On 64-bit architectures 'length' may not fit in a png_uint_32. */
+ /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
if (length > PNG_UINT_31_MAX)
- png_error(png_ptr, "length exceeds PNG maximum");
+ png_error(png_ptr, "length exceeds PNG maxima");
png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
png_write_chunk_data(png_ptr, data, length);
@@ -207,10 +191,10 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
/* This is the API that calls the internal function above. */
void PNGAPI
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
- png_const_bytep data, size_t length)
+ png_const_bytep data, png_size_t length)
{
png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
- length);
+ length);
}
/* This is used below to find the size of an image to pass to png_deflate_claim,
@@ -220,14 +204,14 @@ png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
static png_alloc_size_t
png_image_size(png_structrp png_ptr)
{
- /* Only return sizes up to the maximum of a png_uint_32; do this by limiting
+ /* Only return sizes up to the maximum of a png_uint_32, do this by limiting
* the width and height used to 15 bits.
*/
png_uint_32 h = png_ptr->height;
if (png_ptr->rowbytes < 32768 && h < 32768)
{
- if (png_ptr->interlaced != 0)
+ if (png_ptr->interlaced)
{
/* Interlacing makes the image larger because of the replication of
* both the filter byte and the padding to a byte boundary.
@@ -302,16 +286,17 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
}
}
}
-#endif /* WRITE_OPTIMIZE_CMF */
+#else
+# define optimize_cmf(dp,dl) ((void)0)
+#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
- png_alloc_size_t data_size)
+ png_alloc_size_t data_size)
{
if (png_ptr->zowner != 0)
{
-#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
char msg[64];
PNG_STRING_FROM_CHUNK(msg, owner);
@@ -323,8 +308,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
* are minimal.
*/
(void)png_safecat(msg, (sizeof msg), 10, " using zstream");
-#endif
-#if PNG_RELEASE_BUILD
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
png_warning(png_ptr, msg);
/* Attempt sane error recovery */
@@ -335,9 +319,9 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
}
png_ptr->zowner = 0;
-#else
+# else
png_error(png_ptr, msg);
-#endif
+# endif
}
{
@@ -350,7 +334,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
if (owner == png_IDAT)
{
- if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0)
+ if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)
strategy = png_ptr->zlib_strategy;
else if (png_ptr->do_filter != PNG_FILTER_NONE)
@@ -362,20 +346,20 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
else
{
-#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+# ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
level = png_ptr->zlib_text_level;
method = png_ptr->zlib_text_method;
windowBits = png_ptr->zlib_text_window_bits;
memLevel = png_ptr->zlib_text_mem_level;
strategy = png_ptr->zlib_text_strategy;
-#else
+# else
/* If customization is not supported the values all come from the
* IDAT values except for the strategy, which is fixed to the
* default. (This is the pre-1.6.0 behavior too, although it was
* implemented in a very different way.)
*/
strategy = Z_DEFAULT_STRATEGY;
-#endif
+# endif
}
/* Adjust 'windowBits' down if larger than 'data_size'; to stop this
@@ -402,7 +386,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
}
/* Check against the previous initialized values, if any. */
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) &&
(png_ptr->zlib_set_level != level ||
png_ptr->zlib_set_method != method ||
png_ptr->zlib_set_window_bits != windowBits ||
@@ -424,15 +408,15 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
png_ptr->zstream.avail_out = 0;
/* Now initialize if required, setting the new parameters, otherwise just
- * do a simple reset to the previous parameters.
+ * to a simple reset to the previous parameters.
*/
- if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
ret = deflateReset(&png_ptr->zstream);
else
{
ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
- memLevel, strategy);
+ memLevel, strategy);
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
@@ -485,15 +469,15 @@ png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
*/
typedef struct
{
- png_const_bytep input; /* The uncompressed input data */
- png_alloc_size_t input_len; /* Its length */
- png_uint_32 output_len; /* Final compressed length */
- png_byte output[1024]; /* First block of output */
+ png_const_bytep input; /* The uncompressed input data */
+ png_alloc_size_t input_len; /* Its length */
+ png_uint_32 output_len; /* Final compressed length */
+ png_byte output[1024]; /* First block of output */
} compression_state;
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
- png_alloc_size_t input_len)
+ png_alloc_size_t input_len)
{
comp->input = input;
comp->input_len = input_len;
@@ -503,12 +487,12 @@ png_text_compress_init(compression_state *comp, png_const_bytep input,
/* Compress the data in the compression state input */
static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
- compression_state *comp, png_uint_32 prefix_len)
+ compression_state *comp, png_uint_32 prefix_len)
{
int ret;
/* To find the length of the output it is necessary to first compress the
- * input. The result is buffered rather than using the two-pass algorithm
+ * input, the result is buffered rather than using the two-pass algorithm
* that is used on the inflate side; deflate is assumed to be slower and a
* PNG writer is assumed to have more memory available than a PNG reader.
*
@@ -595,7 +579,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
/* Compress the data */
ret = deflate(&png_ptr->zstream,
- input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+ input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
/* Claw back input data that was not consumed (because avail_in is
* reset above every time round the loop).
@@ -605,7 +589,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
}
while (ret == Z_OK);
- /* There may be some space left in the last output buffer. This needs to
+ /* There may be some space left in the last output buffer, this needs to
* be subtracted from output_len.
*/
output_len -= png_ptr->zstream.avail_out;
@@ -628,15 +612,14 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
/* Reset zlib for another zTXt/iTXt or image data */
png_ptr->zowner = 0;
- /* The only success case is Z_STREAM_END, input_len must be 0; if not this
+ /* The only success case is Z_STREAM_END, input_len must be 0, if not this
* is an internal error.
*/
if (ret == Z_STREAM_END && input_len == 0)
{
-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
/* Fix up the deflate header, if required */
optimize_cmf(comp->output, comp->input_len);
-#endif
+
/* But Z_OK is returned, not Z_STREAM_END; this allows the claim
* function above to return Z_STREAM_END on an error (though it never
* does in the current versions of zlib.)
@@ -679,7 +662,89 @@ png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
if (output_len > 0)
png_error(png_ptr, "error writing ancillary chunked compressed data");
}
-#endif /* WRITE_COMPRESSED_TEXT */
+#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
+ * trailing '\0'). If this routine returns 0 then there was no keyword, or a
+ * valid one could not be generated, and the caller must png_error.
+ */
+static png_uint_32
+png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
+{
+ png_const_charp orig_key = key;
+ png_uint_32 key_len = 0;
+ int bad_character = 0;
+ int space = 1;
+
+ png_debug(1, "in png_check_keyword");
+
+ if (key == NULL)
+ {
+ *new_key = 0;
+ return 0;
+ }
+
+ while (*key && key_len < 79)
+ {
+ png_byte ch = (png_byte)(0xff & *key++);
+
+ if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
+ *new_key++ = ch, ++key_len, space = 0;
+
+ else if (!space)
+ {
+ /* A space or an invalid character when one wasn't seen immediately
+ * before; output just a space.
+ */
+ *new_key++ = 32, ++key_len, space = 1;
+
+ /* If the character was not a space then it is invalid. */
+ if (ch != 32)
+ bad_character = ch;
+ }
+
+ else if (!bad_character)
+ bad_character = ch; /* just skip it, record the first error */
+ }
+
+ if (key_len > 0 && space) /* trailing space */
+ {
+ --key_len, --new_key;
+ if (!bad_character)
+ bad_character = 32;
+ }
+
+ /* Terminate the keyword */
+ *new_key = 0;
+
+ if (key_len == 0)
+ return 0;
+
+ /* Try to only output one warning per keyword: */
+ if (*key) /* keyword too long */
+ png_warning(png_ptr, "keyword truncated");
+
+ else if (bad_character)
+ {
+ PNG_WARNING_PARAMETERS(p)
+
+ png_warning_parameter(p, 1, orig_key);
+ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
+
+ png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
+ }
+
+ return key_len;
+}
+#endif
/* Write the IHDR chunk, and update the png_struct with the necessary
* information. Note that the rest of this code depends upon this
@@ -691,7 +756,6 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
int interlace_type)
{
png_byte buf[13]; /* Buffer to store the IHDR info */
- int is_invalid_depth;
png_debug(1, "in png_write_IHDR");
@@ -717,11 +781,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break;
case PNG_COLOR_TYPE_RGB:
- is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
- is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+ if (bit_depth != 8 && bit_depth != 16)
+#else
+ if (bit_depth != 8)
#endif
- if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGB image");
png_ptr->channels = 3;
@@ -743,22 +807,18 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
- is_invalid_depth = (bit_depth != 8);
-#ifdef PNG_WRITE_16BIT_SUPPORTED
- is_invalid_depth = (is_invalid_depth && bit_depth != 16);
-#endif
- if (is_invalid_depth)
+ if (bit_depth != 8 && bit_depth != 16)
png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
png_ptr->channels = 2;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
- is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
- is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+ if (bit_depth != 8 && bit_depth != 16)
+#else
+ if (bit_depth != 8)
#endif
- if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGBA image");
png_ptr->channels = 4;
@@ -785,8 +845,8 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
*/
if (
#ifdef PNG_MNG_FEATURES_SUPPORTED
- !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
- ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
(color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
(filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
@@ -808,7 +868,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
interlace_type=PNG_INTERLACE_NONE;
#endif
- /* Save the relevant information */
+ /* Save the relevent information */
png_ptr->bit_depth = (png_byte)bit_depth;
png_ptr->color_type = (png_byte)color_type;
png_ptr->interlaced = (png_byte)interlace_type;
@@ -836,9 +896,9 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
buf[12] = (png_byte)interlace_type;
/* Write the chunk */
- png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
+ png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
- if ((png_ptr->do_filter) == PNG_NO_FILTERS)
+ if (!(png_ptr->do_filter))
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
png_ptr->bit_depth < 8)
@@ -859,20 +919,17 @@ void /* PRIVATE */
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
png_uint_32 num_pal)
{
- png_uint_32 max_palette_length, i;
+ png_uint_32 i;
png_const_colorp pal_ptr;
png_byte buf[3];
png_debug(1, "in png_write_PLTE");
- max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
- (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
-
if ((
#ifdef PNG_MNG_FEATURES_SUPPORTED
- (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
#endif
- num_pal == 0) || num_pal > max_palette_length)
+ num_pal == 0) || num_pal > 256)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
@@ -886,7 +943,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
}
}
- if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
{
png_warning(png_ptr,
"Ignoring request to write a PLTE chunk in grayscale PNG");
@@ -905,7 +962,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
buf[0] = pal_ptr->red;
buf[1] = pal_ptr->green;
buf[2] = pal_ptr->blue;
- png_write_chunk_data(png_ptr, buf, 3);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
}
#else
@@ -919,7 +976,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
buf[0] = pal_ptr[i].red;
buf[1] = pal_ptr[i].green;
buf[2] = pal_ptr[i].blue;
- png_write_chunk_data(png_ptr, buf, 3);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
}
#endif
@@ -941,12 +998,12 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
* Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
*
* The routine manages the acquire and release of the png_ptr->zstream by
- * checking and (at the end) clearing png_ptr->zowner; it does some sanity
+ * checking and (at the end) clearing png_ptr->zowner, it does some sanity
* checks on the 'mode' flags while doing this.
*/
void /* PRIVATE */
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
- png_alloc_size_t input_len, int flush)
+ png_alloc_size_t input_len, int flush)
{
if (png_ptr->zowner != png_IDAT)
{
@@ -958,7 +1015,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
if (png_ptr->zbuffer_list == NULL)
{
png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
- png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
png_ptr->zbuffer_list->next = NULL;
}
@@ -1001,7 +1058,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
input_len += png_ptr->zstream.avail_in;
png_ptr->zstream.avail_in = 0;
- /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note
+ /* OUTPUT: write complete IDAT chunks when avail_out drops to zero, note
* that these two zstream fields are preserved across the calls, therefore
* there is no need to set these up on entry to the loop.
*/
@@ -1013,14 +1070,13 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
/* Write an IDAT containing the data then reset the buffer. The
* first IDAT may need deflate header optimization.
*/
-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
- if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
optimize_cmf(data, png_image_size(png_ptr));
-#endif
+# endif
- if (size > 0)
- png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->zstream.next_out = data;
@@ -1034,7 +1090,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
continue;
}
- /* The order of these checks doesn't matter much; it just affects which
+ /* The order of these checks doesn't matter much; it just effect which
* possible error might be detected if multiple things go wrong at once.
*/
if (ret == Z_OK) /* most likely return code! */
@@ -1060,14 +1116,13 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
png_bytep data = png_ptr->zbuffer_list->output;
uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
-#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
- if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
- png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
- optimize_cmf(data, png_image_size(png_ptr));
-#endif
+# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ optimize_cmf(data, png_image_size(png_ptr));
+# endif
- if (size > 0)
- png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->zstream.avail_out = 0;
png_ptr->zstream.next_out = NULL;
png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@ -1091,7 +1146,7 @@ png_write_IEND(png_structrp png_ptr)
{
png_debug(1, "in png_write_IEND");
- png_write_complete_chunk(png_ptr, png_IEND, NULL, 0);
+ png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
png_ptr->mode |= PNG_HAVE_IEND;
}
@@ -1106,7 +1161,7 @@ png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
/* file_gamma is saved in 1/100,000ths */
png_save_uint_32(buf, (png_uint_32)file_gamma);
- png_write_complete_chunk(png_ptr, png_gAMA, buf, 4);
+ png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
}
#endif
@@ -1124,7 +1179,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
"Invalid sRGB rendering intent specified");
buf[0]=(png_byte)srgb_intent;
- png_write_complete_chunk(png_ptr, png_sRGB, buf, 1);
+ png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
}
#endif
@@ -1132,12 +1187,12 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
/* Write an iCCP chunk */
void /* PRIVATE */
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
- png_const_bytep profile, png_uint_32 profile_len)
+ png_const_bytep profile)
{
png_uint_32 name_len;
+ png_uint_32 profile_len;
png_byte new_name[81]; /* 1 byte for the compression byte */
compression_state comp;
- png_uint_32 temp;
png_debug(1, "in png_write_iCCP");
@@ -1147,14 +1202,12 @@ png_write_iCCP(png_structrp png_ptr, png_const_charp name,
if (profile == NULL)
png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
+ profile_len = png_get_uint_32(profile);
+
if (profile_len < 132)
png_error(png_ptr, "ICC profile too short");
- if (png_get_uint_32(profile) != profile_len)
- png_error(png_ptr, "Incorrect data in iCCP");
-
- temp = (png_uint_32) (*(profile+8));
- if (temp > 3 && (profile_len & 0x03))
+ if (profile_len & 0x03)
png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
{
@@ -1198,8 +1251,8 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_uint_32 name_len;
png_byte new_name[80];
png_byte entrybuf[10];
- size_t entry_size = (spalette->depth == 8 ? 6 : 10);
- size_t palette_size = entry_size * (size_t)spalette->nentries;
+ png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
+ png_size_t palette_size = entry_size * spalette->nentries;
png_sPLT_entryp ep;
#ifndef PNG_POINTER_INDEXING_SUPPORTED
int i;
@@ -1216,9 +1269,10 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size));
- png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1));
+ png_write_chunk_data(png_ptr, (png_bytep)new_name,
+ (png_size_t)(name_len + 1));
- png_write_chunk_data(png_ptr, &spalette->depth, 1);
+ png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
/* Loop through each palette entry, writing appropriately */
#ifdef PNG_POINTER_INDEXING_SUPPORTED
@@ -1280,12 +1334,12 @@ void /* PRIVATE */
png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
{
png_byte buf[4];
- size_t size;
+ png_size_t size;
png_debug(1, "in png_write_sBIT");
/* Make sure we don't depend upon the order of PNG_COLOR_8 */
- if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ if (color_type & PNG_COLOR_MASK_COLOR)
{
png_byte maxbits;
@@ -1318,7 +1372,7 @@ png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
size = 1;
}
- if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ if (color_type & PNG_COLOR_MASK_ALPHA)
{
if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
{
@@ -1380,12 +1434,12 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
/* Write the chunk out as it is */
png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
- (size_t)num_trans);
+ (png_size_t)num_trans);
}
else if (color_type == PNG_COLOR_TYPE_GRAY)
{
- /* One 16-bit value */
+ /* One 16 bit value */
if (tran->gray >= (1 << png_ptr->bit_depth))
{
png_app_warning(png_ptr,
@@ -1395,27 +1449,27 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
}
png_save_uint_16(buf, tran->gray);
- png_write_complete_chunk(png_ptr, png_tRNS, buf, 2);
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
}
else if (color_type == PNG_COLOR_TYPE_RGB)
{
- /* Three 16-bit values */
+ /* Three 16 bit values */
png_save_uint_16(buf, tran->red);
png_save_uint_16(buf + 2, tran->green);
png_save_uint_16(buf + 4, tran->blue);
#ifdef PNG_WRITE_16BIT_SUPPORTED
- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
#else
- if ((buf[0] | buf[2] | buf[4]) != 0)
+ if (buf[0] | buf[2] | buf[4])
#endif
{
png_app_warning(png_ptr,
- "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
return;
}
- png_write_complete_chunk(png_ptr, png_tRNS, buf, 6);
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
}
else
@@ -1438,8 +1492,8 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
{
if (
#ifdef PNG_MNG_FEATURES_SUPPORTED
- (png_ptr->num_palette != 0 ||
- (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&
+ (png_ptr->num_palette ||
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
#endif
back->index >= png_ptr->num_palette)
{
@@ -1448,28 +1502,27 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
}
buf[0] = back->index;
- png_write_complete_chunk(png_ptr, png_bKGD, buf, 1);
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
}
- else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ else if (color_type & PNG_COLOR_MASK_COLOR)
{
png_save_uint_16(buf, back->red);
png_save_uint_16(buf + 2, back->green);
png_save_uint_16(buf + 4, back->blue);
#ifdef PNG_WRITE_16BIT_SUPPORTED
- if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
#else
- if ((buf[0] | buf[2] | buf[4]) != 0)
+ if (buf[0] | buf[2] | buf[4])
#endif
{
png_warning(png_ptr,
- "Ignoring attempt to write 16-bit bKGD chunk "
- "when bit_depth is 8");
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
return;
}
- png_write_complete_chunk(png_ptr, png_bKGD, buf, 6);
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
}
else
@@ -1483,100 +1536,11 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
}
png_save_uint_16(buf, back->gray);
- png_write_complete_chunk(png_ptr, png_bKGD, buf, 2);
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
}
}
#endif
-#ifdef PNG_WRITE_cICP_SUPPORTED
-/* Write the cICP data */
-void /* PRIVATE */
-png_write_cICP(png_structrp png_ptr,
- png_byte colour_primaries, png_byte transfer_function,
- png_byte matrix_coefficients, png_byte video_full_range_flag)
-{
- png_byte buf[4];
-
- png_debug(1, "in png_write_cICP");
-
- png_write_chunk_header(png_ptr, png_cICP, 4);
-
- buf[0] = colour_primaries;
- buf[1] = transfer_function;
- buf[2] = matrix_coefficients;
- buf[3] = video_full_range_flag;
- png_write_chunk_data(png_ptr, buf, 4);
-
- png_write_chunk_end(png_ptr);
-}
-#endif
-
-#ifdef PNG_WRITE_cLLI_SUPPORTED
-void /* PRIVATE */
-png_write_cLLI_fixed(png_structrp png_ptr, png_uint_32 maxCLL,
- png_uint_32 maxFALL)
-{
- png_byte buf[8];
-
- png_debug(1, "in png_write_cLLI_fixed");
-
- png_save_uint_32(buf, maxCLL);
- png_save_uint_32(buf + 4, maxFALL);
-
- png_write_complete_chunk(png_ptr, png_cLLI, buf, 8);
-}
-#endif
-
-#ifdef PNG_WRITE_mDCV_SUPPORTED
-void /* PRIVATE */
-png_write_mDCV_fixed(png_structrp png_ptr,
- png_uint_16 red_x, png_uint_16 red_y,
- png_uint_16 green_x, png_uint_16 green_y,
- png_uint_16 blue_x, png_uint_16 blue_y,
- png_uint_16 white_x, png_uint_16 white_y,
- png_uint_32 maxDL, png_uint_32 minDL)
-{
- png_byte buf[24];
-
- png_debug(1, "in png_write_mDCV_fixed");
-
- png_save_uint_16(buf + 0, red_x);
- png_save_uint_16(buf + 2, red_y);
- png_save_uint_16(buf + 4, green_x);
- png_save_uint_16(buf + 6, green_y);
- png_save_uint_16(buf + 8, blue_x);
- png_save_uint_16(buf + 10, blue_y);
- png_save_uint_16(buf + 12, white_x);
- png_save_uint_16(buf + 14, white_y);
- png_save_uint_32(buf + 16, maxDL);
- png_save_uint_32(buf + 20, minDL);
-
- png_write_complete_chunk(png_ptr, png_mDCV, buf, 24);
-}
-#endif
-
-#ifdef PNG_WRITE_eXIf_SUPPORTED
-/* Write the Exif data */
-void /* PRIVATE */
-png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
-{
- int i;
- png_byte buf[1];
-
- png_debug(1, "in png_write_eXIf");
-
- png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));
-
- for (i = 0; i < num_exif; i++)
- {
- buf[0] = exif[i];
- png_write_chunk_data(png_ptr, buf, 1);
- }
-
- png_write_chunk_end(png_ptr);
-}
-#endif
-
#ifdef PNG_WRITE_hIST_SUPPORTED
/* Write the histogram */
void /* PRIVATE */
@@ -1601,7 +1565,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
for (i = 0; i < num_hist; i++)
{
png_save_uint_16(buf, hist[i]);
- png_write_chunk_data(png_ptr, buf, 2);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
}
png_write_chunk_end(png_ptr);
@@ -1612,7 +1576,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
/* Write a tEXt chunk */
void /* PRIVATE */
png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
- size_t text_len)
+ png_size_t text_len)
{
png_uint_32 key_len;
png_byte new_key[80];
@@ -1644,7 +1608,7 @@ png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
*/
png_write_chunk_data(png_ptr, new_key, key_len + 1);
- if (text_len != 0)
+ if (text_len)
png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
png_write_chunk_end(png_ptr);
@@ -1655,13 +1619,14 @@ png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
/* Write a compressed text chunk */
void /* PRIVATE */
png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
- int compression)
+ png_size_t text_len, int compression)
{
png_uint_32 key_len;
png_byte new_key[81];
compression_state comp;
png_debug(1, "in png_write_zTXt");
+ PNG_UNUSED(text_len) /* Always use strlen */
if (compression == PNG_TEXT_COMPRESSION_NONE)
{
@@ -1683,7 +1648,7 @@ png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
/* Compute the compressed data; do it now for the length */
png_text_compress_init(&comp, (png_const_bytep)text,
- text == NULL ? 0 : strlen(text));
+ text == NULL ? 0 : strlen(text));
if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
@@ -1709,7 +1674,7 @@ png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
png_const_charp lang, png_const_charp lang_key, png_const_charp text)
{
png_uint_32 key_len, prefix_len;
- size_t lang_len, lang_key_len;
+ png_size_t lang_len, lang_key_len;
png_byte new_key[82];
compression_state comp;
@@ -1769,7 +1734,7 @@ png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
- if (compression != 0)
+ if (compression)
{
if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
@@ -1792,11 +1757,11 @@ png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
- if (compression != 0)
+ if (compression)
png_write_compressed_data_out(png_ptr, &comp);
else
- png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);
png_write_chunk_end(png_ptr);
}
@@ -1819,7 +1784,7 @@ png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
png_save_int_32(buf + 4, y_offset);
buf[8] = (png_byte)unit_type;
- png_write_complete_chunk(png_ptr, png_oFFs, buf, 9);
+ png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
}
#endif
#ifdef PNG_WRITE_pCAL_SUPPORTED
@@ -1830,8 +1795,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_charpp params)
{
png_uint_32 purpose_len;
- size_t units_len, total_len;
- size_t *params_len;
+ png_size_t units_len, total_len;
+ png_size_tp params_len;
png_byte buf[10];
png_byte new_purpose[80];
int i;
@@ -1853,8 +1818,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_debug1(3, "pCAL units length = %d", (int)units_len);
total_len = purpose_len + units_len + 10;
- params_len = (size_t *)png_malloc(png_ptr,
- (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t))));
+ params_len = (png_size_tp)png_malloc(png_ptr,
+ (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
/* Find the length of each parameter, making sure we don't count the
* null terminator for the last parameter.
@@ -1874,8 +1839,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)type;
buf[9] = (png_byte)nparams;
- png_write_chunk_data(png_ptr, buf, 10);
- png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
for (i = 0; i < nparams; i++)
{
@@ -1894,7 +1859,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
png_const_charp height)
{
png_byte buf[64];
- size_t wlen, hlen, total_len;
+ png_size_t wlen, hlen, total_len;
png_debug(1, "in png_write_sCAL_s");
@@ -1935,7 +1900,7 @@ png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
png_save_uint_32(buf + 4, y_pixels_per_unit);
buf[8] = (png_byte)unit_type;
- png_write_complete_chunk(png_ptr, png_pHYs, buf, 9);
+ png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
}
#endif
@@ -1965,7 +1930,7 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
buf[5] = mod_time->minute;
buf[6] = mod_time->second;
- png_write_complete_chunk(png_ptr, png_tIME, buf, 7);
+ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
}
#endif
@@ -1973,13 +1938,25 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
void /* PRIVATE */
png_write_start_row(png_structrp png_ptr)
{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
png_alloc_size_t buf_size;
int usr_pixel_depth;
-#ifdef PNG_WRITE_FILTER_SUPPORTED
- png_byte filters;
-#endif
-
png_debug(1, "in png_write_start_row");
usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
@@ -1990,61 +1967,56 @@ png_write_start_row(png_structrp png_ptr)
png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
/* Set up row buffer */
- png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
#ifdef PNG_WRITE_FILTER_SUPPORTED
- filters = png_ptr->do_filter;
-
- if (png_ptr->height == 1)
- filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
-
- if (png_ptr->width == 1)
- filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
-
- if (filters == 0)
- filters = PNG_FILTER_NONE;
-
- png_ptr->do_filter = filters;
-
- if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |
- PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)
+ /* Set up filtering buffer, if using this filter */
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
{
- int num_filters = 0;
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
- png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
-
- if (filters & PNG_FILTER_SUB)
- num_filters++;
-
- if (filters & PNG_FILTER_UP)
- num_filters++;
-
- if (filters & PNG_FILTER_AVG)
- num_filters++;
-
- if (filters & PNG_FILTER_PAETH)
- num_filters++;
-
- if (num_filters > 1)
- png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr,
- buf_size));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
}
- /* We only need to keep the previous row if we are using one of the following
- * filters.
- */
- if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
- png_ptr->prev_row = png_voidcast(png_bytep,
- png_calloc(png_ptr, buf_size));
-#endif /* WRITE_FILTER */
+ /* We only need to keep the previous row if we are using one of these. */
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+ {
+ /* Set up previous row buffer */
+ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
+
+ if (png_ptr->do_filter & PNG_FILTER_UP)
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* If interlaced, we need to set up width and height of pass */
- if (png_ptr->interlaced != 0)
+ if (png_ptr->interlaced)
{
- if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ if (!(png_ptr->transformations & PNG_INTERLACE))
{
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
png_pass_ystart[0]) / png_pass_yinc[0];
@@ -2072,6 +2044,22 @@ png_write_start_row(png_structrp png_ptr)
void /* PRIVATE */
png_write_finish_row(png_structrp png_ptr)
{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
png_debug(1, "in png_write_finish_row");
/* Next row */
@@ -2083,10 +2071,10 @@ png_write_finish_row(png_structrp png_ptr)
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* If interlaced, go to next pass */
- if (png_ptr->interlaced != 0)
+ if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
- if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ if (png_ptr->transformations & PNG_INTERLACE)
{
png_ptr->pass++;
}
@@ -2111,7 +2099,7 @@ png_write_finish_row(png_structrp png_ptr)
png_pass_ystart[png_ptr->pass]) /
png_pass_yinc[png_ptr->pass];
- if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ if (png_ptr->transformations & PNG_INTERLACE)
break;
} while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
@@ -2123,8 +2111,8 @@ png_write_finish_row(png_structrp png_ptr)
{
if (png_ptr->prev_row != NULL)
memset(png_ptr->prev_row, 0,
- PNG_ROWBYTES(png_ptr->usr_channels *
- png_ptr->usr_bit_depth, png_ptr->width) + 1);
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+ png_ptr->usr_bit_depth, png_ptr->width)) + 1);
return;
}
@@ -2147,6 +2135,14 @@ png_write_finish_row(png_structrp png_ptr)
void /* PRIVATE */
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
png_debug(1, "in png_do_write_interlace");
/* We don't have to do anything on the last pass (6) */
@@ -2159,7 +2155,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
{
png_bytep sp;
png_bytep dp;
- unsigned int shift;
+ int shift;
int d;
int value;
png_uint_32 i;
@@ -2172,7 +2168,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass])
{
- sp = row + (size_t)(i >> 3);
+ sp = row + (png_size_t)(i >> 3);
value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
d |= (value << shift);
@@ -2197,7 +2193,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
{
png_bytep sp;
png_bytep dp;
- unsigned int shift;
+ int shift;
int d;
int value;
png_uint_32 i;
@@ -2210,7 +2206,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass])
{
- sp = row + (size_t)(i >> 2);
+ sp = row + (png_size_t)(i >> 2);
value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
d |= (value << shift);
@@ -2234,7 +2230,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
{
png_bytep sp;
png_bytep dp;
- unsigned int shift;
+ int shift;
int d;
int value;
png_uint_32 i;
@@ -2246,7 +2242,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass])
{
- sp = row + (size_t)(i >> 1);
+ sp = row + (png_size_t)(i >> 1);
value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
d |= (value << shift);
@@ -2272,7 +2268,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
png_bytep dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
- size_t pixel_bytes;
+ png_size_t pixel_bytes;
/* Start at the beginning */
dp = row;
@@ -2285,7 +2281,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
i += png_pass_inc[pass])
{
/* Find out where the original pixel is */
- sp = row + (size_t)i * pixel_bytes;
+ sp = row + (png_size_t)i * pixel_bytes;
/* Move the pixel */
if (dp != sp)
@@ -2309,308 +2305,49 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
}
#endif
-
/* This filters the row, chooses which filter to use, if it has not already
* been specified by the application, and then writes the row out with the
* chosen filter.
*/
-static void /* PRIVATE */
-png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
- size_t row_bytes);
-
-#ifdef PNG_WRITE_FILTER_SUPPORTED
-static size_t /* PRIVATE */
-png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes, size_t lmins)
-{
- png_bytep rp, dp, lp;
- size_t i;
- size_t sum = 0;
- unsigned int v;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- v = *dp = *rp;
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
- }
-
- for (lp = png_ptr->row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- return sum;
-}
-
-static void /* PRIVATE */
-png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes)
-{
- png_bytep rp, dp, lp;
- size_t i;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
- i++, rp++, dp++)
- {
- *dp = *rp;
- }
-
- for (lp = png_ptr->row_buf + 1; i < row_bytes;
- i++, rp++, lp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
- }
-}
-
-static size_t /* PRIVATE */
-png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins)
-{
- png_bytep rp, dp, pp;
- size_t i;
- size_t sum = 0;
- unsigned int v;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- return sum;
-}
-static void /* PRIVATE */
-png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes)
-{
- png_bytep rp, dp, pp;
- size_t i;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < row_bytes;
- i++, rp++, pp++, dp++)
- {
- *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
- }
-}
-
-static size_t /* PRIVATE */
-png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes, size_t lmins)
-{
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
- size_t sum = 0;
- unsigned int v;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
-
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
- }
-
- for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
-
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- return sum;
-}
-static void /* PRIVATE */
-png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes)
-{
- png_bytep rp, dp, pp, lp;
- png_uint_32 i;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
- }
-
- for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
- & 0xff);
- }
-}
-
-static size_t /* PRIVATE */
-png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes, size_t lmins)
-{
- png_bytep rp, dp, pp, cp, lp;
- size_t i;
- size_t sum = 0;
- unsigned int v;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < bpp; i++)
- {
- v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
-
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
- }
-
- for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
- i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
-
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
-
- if (sum > lmins) /* We are already worse, don't continue. */
- break;
- }
-
- return sum;
-}
-static void /* PRIVATE */
-png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp,
- size_t row_bytes)
-{
- png_bytep rp, dp, pp, cp, lp;
- size_t i;
-
- png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
-
- for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
- pp = png_ptr->prev_row + 1; i < bpp; i++)
- {
- *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
- }
-
- for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
- i++)
- {
- int a, b, c, pa, pb, pc, p;
-
- b = *pp++;
- c = *cp++;
- a = *lp++;
-
- p = b - c;
- pc = a - c;
-
-#ifdef PNG_USE_ABS
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-#else
- pa = p < 0 ? -p : p;
- pb = pc < 0 ? -pc : pc;
- pc = (p + pc) < 0 ? -(p + pc) : p + pc;
-#endif
-
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
-
- *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
- }
-}
-#endif /* WRITE_FILTER */
+static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+ png_size_t row_bytes);
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
void /* PRIVATE */
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
{
-#ifndef PNG_WRITE_FILTER_SUPPORTED
- png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
-#else
- unsigned int filter_to_do = png_ptr->do_filter;
- png_bytep row_buf;
png_bytep best_row;
- png_uint_32 bpp;
- size_t mins;
- size_t row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_bytep prev_row, row_buf;
+ png_uint_32 mins, bpp;
+ png_byte filter_to_do = png_ptr->do_filter;
+ png_size_t row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ int num_p_filters = png_ptr->num_prev_filters;
+#endif
png_debug(1, "in png_write_find_filter");
+#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
+ {
+ /* These will never be selected so we need not test them. */
+ filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+ }
+#endif
+
/* Find out how many bytes offset each pixel is */
bpp = (row_info->pixel_depth + 7) >> 3;
- row_buf = png_ptr->row_buf;
- mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the
- running sum */;
+ prev_row = png_ptr->prev_row;
+#endif
+ best_row = png_ptr->row_buf;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ row_buf = best_row;
+ mins = PNG_MAXSUM;
/* The prediction method we use is to find which method provides the
* smallest value when summing the absolute values of the distances
@@ -2640,38 +2377,57 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* We don't need to test the 'no filter' case if this is the only filter
* that has been chosen, as it doesn't actually do anything to the data.
*/
- best_row = png_ptr->row_buf;
-
- if (PNG_SIZE_MAX/128 <= row_bytes)
+ if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
{
- /* Overflow can occur in the calculation, just select the lowest set
- * filter.
- */
- filter_to_do &= 0U-filter_to_do;
- }
- else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
- filter_to_do != PNG_FILTER_NONE)
- {
- /* Overflow not possible and multiple filters in the list, including the
- * 'none' filter.
- */
png_bytep rp;
- size_t sum = 0;
- size_t i;
- unsigned int v;
+ png_uint_32 sum = 0;
+ png_size_t i;
+ int v;
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
- for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
- {
- v = *rp;
-#ifdef PNG_USE_ABS
- sum += 128 - abs((int)v - 128);
-#else
- sum += (v < 128) ? v : 256 - v;
-#endif
- }
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
}
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ png_uint_32 sumhi, sumlo;
+ int j;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+ /* Reduce the sum if we match any of the previous rows */
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ /* Factor in the cost of this filter (this is here for completeness,
+ * but it makes no sense to have a "cost" for the NONE filter, as
+ * it has the minimum possible computational cost - none).
+ */
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
mins = sum;
}
@@ -2679,117 +2435,561 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */
{
- png_setup_sub_row_only(png_ptr, bpp, row_bytes);
- best_row = png_ptr->try_row;
+ png_bytep rp, lp, dp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+
+ best_row = png_ptr->sub_row;
}
- else if ((filter_to_do & PNG_FILTER_SUB) != 0)
+ else if (filter_to_do & PNG_FILTER_SUB)
{
- size_t sum;
- size_t lmins = mins;
+ png_bytep rp, dp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
- sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* We temporarily increase the "minimum sum" by the factor we
+ * would reduce the sum of this filter, so that we can do the
+ * early exit comparison without scaling the sum each time.
+ */
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->try_row;
- if (png_ptr->tst_row != NULL)
- {
- png_ptr->try_row = png_ptr->tst_row;
- png_ptr->tst_row = best_row;
- }
+ best_row = png_ptr->sub_row;
}
}
/* Up filter */
if (filter_to_do == PNG_FILTER_UP)
{
- png_setup_up_row_only(png_ptr, row_bytes);
- best_row = png_ptr->try_row;
+ png_bytep rp, dp, pp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+
+ best_row = png_ptr->up_row;
}
- else if ((filter_to_do & PNG_FILTER_UP) != 0)
+ else if (filter_to_do & PNG_FILTER_UP)
{
- size_t sum;
- size_t lmins = mins;
+ png_bytep rp, dp, pp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
- sum = png_setup_up_row(png_ptr, row_bytes, lmins);
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->try_row;
- if (png_ptr->tst_row != NULL)
- {
- png_ptr->try_row = png_ptr->tst_row;
- png_ptr->tst_row = best_row;
- }
+ best_row = png_ptr->up_row;
}
}
/* Avg filter */
if (filter_to_do == PNG_FILTER_AVG)
{
- png_setup_avg_row_only(png_ptr, bpp, row_bytes);
- best_row = png_ptr->try_row;
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+ best_row = png_ptr->avg_row;
}
- else if ((filter_to_do & PNG_FILTER_AVG) != 0)
+ else if (filter_to_do & PNG_FILTER_AVG)
{
- size_t sum;
- size_t lmins = mins;
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
- sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ =
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
if (sum < mins)
{
mins = sum;
- best_row = png_ptr->try_row;
- if (png_ptr->tst_row != NULL)
- {
- png_ptr->try_row = png_ptr->tst_row;
- png_ptr->tst_row = best_row;
- }
+ best_row = png_ptr->avg_row;
}
}
/* Paeth filter */
if (filter_to_do == PNG_FILTER_PAETH)
{
- png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
- best_row = png_ptr->try_row;
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+ best_row = png_ptr->paeth_row;
}
- else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
+ else if (filter_to_do & PNG_FILTER_PAETH)
{
- size_t sum;
- size_t lmins = mins;
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
- sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+ p = b - c;
+ pc = a - c;
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+ p = a + b - c;
+ pa = abs(p - a);
+ pb = abs(p - b);
+ pc = abs(p - c);
+
+ if (pa <= pb && pa <= pc)
+ p = a;
+
+ else if (pb <= pc)
+ p = b;
+
+ else
+ p = c;
+#endif /* PNG_SLOW_PAETH */
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
if (sum < mins)
{
- best_row = png_ptr->try_row;
- if (png_ptr->tst_row != NULL)
- {
- png_ptr->try_row = png_ptr->tst_row;
- png_ptr->tst_row = best_row;
- }
+ best_row = png_ptr->paeth_row;
}
}
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
/* Do the actual writing of the filtered row data from the chosen filter. */
png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
-#endif /* WRITE_FILTER */
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* Save the type of filter we picked this time for future calculations */
+ if (png_ptr->num_prev_filters > 0)
+ {
+ int j;
+
+ for (j = 1; j < num_p_filters; j++)
+ {
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+ }
+
+ png_ptr->prev_filters[j] = best_row[0];
+ }
+#endif
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
}
/* Do the actual writing of a previously filtered row. */
static void
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
- size_t full_row_length/*includes filter byte*/)
+ png_size_t full_row_length/*includes filter byte*/)
{
png_debug(1, "in png_write_filtered_row");
@@ -2797,7 +2997,6 @@ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
-#ifdef PNG_WRITE_FILTER_SUPPORTED
/* Swap the current and previous rows */
if (png_ptr->prev_row != NULL)
{
@@ -2807,7 +3006,6 @@ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_ptr->prev_row = png_ptr->row_buf;
png_ptr->row_buf = tptr;
}
-#endif /* WRITE_FILTER */
/* Finish row - updates counters and flushes zlib if last row */
png_write_finish_row(png_ptr);
@@ -2820,6 +3018,6 @@ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
{
png_write_flush(png_ptr);
}
-#endif /* WRITE_FLUSH */
+#endif
}
-#endif /* WRITE */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/Windows_Libs/Dev/Render/microprofile/microprofile.config.h b/Windows_Libs/Dev/Render/microprofile/microprofile.config.h
new file mode 100644
index 0000000..7c66cfd
--- /dev/null
+++ b/Windows_Libs/Dev/Render/microprofile/microprofile.config.h
@@ -0,0 +1,4 @@
+
+#define MICROPROFILE_ENABLED 1
+#define MICROPROFILE_GPU_TIMERS_D3D11 1
+#define MICROPROFILE_GPU_TIMERS_D3D12 1
diff --git a/Windows_Libs/Dev/Render/microprofile/microprofile.cpp b/Windows_Libs/Dev/Render/microprofile/microprofile.cpp
new file mode 100644
index 0000000..c4af767
--- /dev/null
+++ b/Windows_Libs/Dev/Render/microprofile/microprofile.cpp
@@ -0,0 +1,16191 @@
+#include "../Profiler.h"
+
+#ifdef ENABLE_PROFILING
+
+#define MICROPROFILE_IMPL
+#include "microprofile.h"
+#if MICROPROFILE_ENABLED
+
+#define BREAK_SKIP() __builtin_trap()
+
+#ifdef _WIN32
+#if !defined(WIN32_LEAN_AND_MEAN)
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include
+#endif
+
+#ifdef _WIN32
+#define MICROPROFILE_MAX_PATH MAX_PATH
+#else
+#define MICROPROFILE_MAX_PATH 1024
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if defined(MICROPROFILE_SYSTEM_STB)
+#include
+#else
+#define STB_SPRINTF_IMPLEMENTATION
+#include "stb/stb_sprintf.h"
+#endif
+
+#if defined(_WIN32) && _MSC_VER == 1700
+#define PRIx64 "llx"
+#define PRIu64 "llu"
+#define PRId64 "lld"
+#else
+#include
+#endif
+
+#define MICROPROFILE_MAX_COUNTERS 512
+#define MICROPROFILE_MAX_COUNTER_NAME_CHARS (MICROPROFILE_MAX_COUNTERS * 16)
+#define MICROPROFILE_MAX_GROUP_INTS (MICROPROFILE_MAX_GROUPS / 32)
+#define MICROPROFILE_MAX_CATEGORIES 16
+#define MICROPROFILE_MAX_GRAPHS 5
+#define MICROPROFILE_GRAPH_HISTORY 128
+#define MICROPROFILE_BUFFER_SIZE ((MICROPROFILE_PER_THREAD_BUFFER_SIZE) / sizeof(MicroProfileLogEntry))
+#define MICROPROFILE_GPU_BUFFER_SIZE ((MICROPROFILE_PER_THREAD_GPU_BUFFER_SIZE) / sizeof(MicroProfileLogEntry))
+#define MICROPROFILE_MAX_CONTEXT_SWITCH_THREADS 256
+#define MICROPROFILE_WEBSOCKET_BUFFER_SIZE (64 << 10)
+#define MICROPROFILE_INVALID_TICK ((uint64_t) - 1)
+#define MICROPROFILE_DROPPED_TICK ((uint64_t) - 2)
+#define MICROPROFILE_INVALID_FRAME ((uint32_t) - 1)
+#define MICROPROFILE_GROUP_MASK_ALL 0xffffffff
+#define MICROPROFILE_MAX_PATCH_ERRORS 32
+#define MICROPROFILE_MAX_MODULE_EXEC_REGIONS 16
+
+#define MP_LOG_TICK_MASK 0x0000ffffffffffff
+#define MP_LOG_INDEX_MASK 0x3fff000000000000
+#define MP_LOG_BEGIN_MASK 0xc000000000000000
+#define MP_LOG_CSTR_MASK 0xe000000000000000
+#define MP_LOG_CSTR_BIT 0x2000000000000000
+#define MP_LOG_PAYLOAD_PTR_MASK (~(MP_LOG_BEGIN_MASK | MP_LOG_CSTR_BIT))
+
+#define MP_LOG_ENTER_LEAVE_MASK 0x8000000000000000
+
+#define MP_LOG_LEAVE 0x0
+#define MP_LOG_ENTER 0x1
+#define MP_LOG_EXTENDED 0x2
+#define MP_LOG_EXTENDED_NO_DATA 0x3
+
+#ifndef MICROPROFILE_SETTINGS_FILE
+#define MICROPROFILE_SETTINGS_FILE "mppresets.cfg"
+#endif
+#ifndef MICROPROFILE_SETTINGS_FILE_BUILTIN
+#define MICROPROFILE_SETTINGS_FILE_BUILTIN "mppresets.builtin.cfg"
+#endif
+#ifndef MICROPROFILE_SETTINGS_FILE_TEMP
+#define MICROPROFILE_SETTINGS_FILE_TEMP ".tmp"
+#endif
+
+// #define MP_LOG_EXTRA_DATA 0x3
+
+static_assert(0 == (MICROPROFILE_MAX_GROUPS % 32), "MICROPROFILE_MAX_GROUPS must be divisible by 32");
+
+enum EMicroProfileTokenExtended
+{
+ ETOKEN_GPU_CPU_TIMESTAMP = 0x3fff,
+ ETOKEN_GPU_CPU_SOURCE_THREAD = 0x3ffe,
+ ETOKEN_META_MARKER = 0x3ffd,
+ ETOKEN_CUSTOM_NAME = 0x3ffc,
+ ETOKEN_CUSTOM_COLOR = 0x3ffb,
+ ETOKEN_CUSTOM_ID = 0x3ffa,
+ ETOKEN_CSTR_PTR = 0x2000, // note, matches MP_LOG_CSTR_BIT
+ ETOKEN_MAX = 0x2000,
+};
+
+enum
+{
+ MICROPROFILE_WEBSOCKET_DIRTY_MENU,
+ MICROPROFILE_WEBSOCKET_DIRTY_ENABLED,
+};
+
+#ifndef MICROPROFILE_ALLOC // redefine all if overriding
+#define MICROPROFILE_ALLOC(nSize, nAlign) MicroProfileAllocAligned(nSize, nAlign);
+#define MICROPROFILE_REALLOC(p, s) realloc(p, s)
+#define MICROPROFILE_FREE(p) MicroProfileFreeAligned(p)
+#define MICROPROFILE_FREE_NON_ALIGNED(p) free(p)
+#endif
+
+#define MP_ALLOC(nSize, nAlign) MicroProfileAllocInternal(nSize, nAlign)
+#define MP_REALLOC(p, s) MicroProfileReallocInternal(p, s)
+#define MP_FREE(p) MicroProfileFreeInternal(p)
+#define MP_ALLOC_OBJECT(T) (T*)MP_ALLOC(sizeof(T), alignof(T))
+#define MP_ALLOC_OBJECT_ARRAY(T, Count) (T*)MP_ALLOC(sizeof(T) * Count, alignof(T))
+
+#ifndef MICROPROFILE_DEBUG
+#define MICROPROFILE_DEBUG 0
+#endif
+
+typedef uint64_t MicroProfileLogEntry;
+
+void MicroProfileSleep(uint32_t nMs);
+template
+T MicroProfileMin(T a, T b);
+template
+T MicroProfileMax(T a, T b);
+template
+T MicroProfileClamp(T a, T min_, T max_);
+int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond);
+float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond);
+uint32_t MicroProfileLogGetType(MicroProfileLogEntry Index);
+uint64_t MicroProfileLogGetTimerIndex(MicroProfileLogEntry Index);
+MicroProfileLogEntry MicroProfileMakeLogIndex(uint64_t nBegin, MicroProfileToken nToken, int64_t nTick);
+int64_t MicroProfileLogTickDifference(MicroProfileLogEntry Start, MicroProfileLogEntry End);
+int64_t MicroProfileLogSetTick(MicroProfileLogEntry e, int64_t nTick);
+uint16_t MicroProfileGetTimerIndex(MicroProfileToken t);
+uint32_t MicroProfileGetGroupMask(MicroProfileToken t);
+MicroProfileToken MicroProfileMakeToken(uint64_t nGroupMask, uint32_t nGroupIndex, uint16_t nTimer);
+bool MicroProfileAnyGroupActive();
+void MicroProfileWriteFile(void* Handle, size_t nSize, const char* pData);
+
+// defer implementation
+#define CONCAT_INTERNAL(x, y) x##y
+#define CONCAT(x, y) CONCAT_INTERNAL(x, y)
+void IntentionallyNotDefinedFunction__(); // DO NOT DEFINE THIS
+template
+struct MicroProfileExitScope
+{
+ T lambda;
+ MicroProfileExitScope(T lambda)
+ : lambda(lambda)
+ {
+ }
+ ~MicroProfileExitScope()
+ {
+ lambda();
+ }
+
+ MicroProfileExitScope(const MicroProfileExitScope& rhs)
+ : lambda(rhs.lambda)
+ {
+ IntentionallyNotDefinedFunction__(); // this is here to ensure the compiler does not create duplicate copies
+ }
+
+ private:
+ MicroProfileExitScope& operator=(const MicroProfileExitScope&);
+};
+
+class MicroProfileExitScopeHelp
+{
+ public:
+ template
+ MicroProfileExitScope operator+(T t)
+ {
+ return t;
+ }
+};
+#define defer const auto& CONCAT(defer__, __LINE__) = MicroProfileExitScopeHelp() + [&]()
+
+//////////////////////////////////////////////////////////////////////////
+// platform IMPL
+void* MicroProfileAllocInternal(size_t nSize, size_t nAlign);
+void MicroProfileFreeInternal(void* pPtr);
+void* MicroProfileReallocInternal(void* pPtr, size_t nSize);
+
+void* MicroProfileAllocAligned(size_t nSize, size_t nAlign);
+void MicroProfileFreeAligned(void* pMem);
+
+#if defined(__APPLE__)
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if TARGET_OS_IPHONE
+#define MICROPROFILE_IOS
+#endif
+
+#define MP_TICK() mach_absolute_time()
+inline int64_t MicroProfileTicksPerSecondCpu_()
+{
+ static int64_t nTicksPerSecond = 0;
+ if(nTicksPerSecond == 0)
+ {
+ mach_timebase_info_data_t sTimebaseInfo;
+ mach_timebase_info(&sTimebaseInfo);
+ nTicksPerSecond = 1000000000ll * sTimebaseInfo.denom / sTimebaseInfo.numer;
+ }
+ return nTicksPerSecond;
+}
+
+int64_t MicroProfileTicksPerSecondCpu()
+{
+ return MicroProfileTicksPerSecondCpu_();
+}
+#define MicroProfileTicksPerSecondCpu MicroProfileTicksPerSecondCpu_
+
+inline uint64_t MicroProfileGetCurrentThreadId()
+{
+ uint64_t tid;
+ pthread_threadid_np(pthread_self(), &tid);
+ return tid;
+}
+
+#include
+
+#define MP_BREAK() __builtin_trap()
+#define MP_THREAD_LOCAL __thread
+#define MP_STRCASECMP strcasecmp
+#define MP_GETCURRENTTHREADID() MicroProfileGetCurrentThreadId()
+#define MP_STRCASESTR strcasestr
+#define MP_THREAD_LOCAL __thread
+#define MP_NOINLINE __attribute__((noinline))
+
+void* MicroProfileAllocAligned(size_t nSize, size_t nAlign)
+{
+ void* p;
+ int result = posix_memalign(&p, nAlign, nSize);
+ if(result != 0)
+ {
+ return nullptr;
+ }
+ return p;
+}
+
+void MicroProfileFreeAligned(void* pMem)
+{
+ free(pMem);
+}
+
+#elif defined(_WIN32)
+#include
+#include
+#include
+int64_t MicroProfileGetTick();
+#define MP_TICK() MicroProfileGetTick()
+#define MP_BREAK() __debugbreak()
+#define MP_THREAD_LOCAL __declspec(thread)
+#define MP_STRCASECMP _stricmp
+#define MP_GETCURRENTTHREADID() GetCurrentThreadId()
+#define MP_STRCASESTR StrStrI
+#define MP_THREAD_LOCAL __declspec(thread)
+#define MP_NOINLINE __declspec(noinline)
+
+#ifndef MICROPROFILE_WIN32_TRAP_ALLOCATOR
+#define MICROPROFILE_WIN32_TRAP_ALLOCATOR 0
+#endif
+
+#if MICROPROFILE_WIN32_TRAP_ALLOCATOR
+// minimal trap allocator
+#define PAGE_SIZE (4096)
+void* MicroProfileAllocAligned(size_t nSize, size_t nAlign)
+{
+ (void)nAlign;
+ size_t nAlignedSize = (nSize + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
+ size_t nDelta = nAlignedSize - nSize;
+ size_t nFullSize = nAlignedSize + 2 * PAGE_SIZE;
+
+ void* ptr = VirtualAlloc(0, nFullSize, MEM_RESERVE, PAGE_READWRITE);
+ intptr_t intptr = (intptr_t)ptr;
+
+ void* pResult = VirtualAlloc((void*)(intptr + PAGE_SIZE), nAlignedSize, MEM_COMMIT, PAGE_READWRITE);
+ memset(pResult, 0xf0, nAlignedSize);
+
+ intptr_t page = (intptr_t)pResult;
+ //((char*)page)[-1] = 0x70; //trap test
+ page += nDelta;
+ pResult = (void*)page;
+ memset(pResult, 0xfe, nSize);
+ //((char*)page)[nSize] = 0x70; //trap test
+ return (void*)page;
+}
+
+void MicroProfileFreeAligned(void* pMem)
+{
+ intptr_t intptr = (intptr_t)pMem;
+ intptr = (intptr & (~(PAGE_SIZE - 1))) - PAGE_SIZE;
+ VirtualFree(pMem, 0, MEM_RELEASE);
+}
+#else
+void* MicroProfileAllocAligned(size_t nSize, size_t nAlign)
+{
+ return _aligned_malloc(nSize, nAlign);
+}
+
+void MicroProfileFreeAligned(void* pMem)
+{
+ _aligned_free(pMem);
+}
+#endif
+
+#else
+
+#ifndef MICROPROFILE_CUSTOM_PLATFORM
+#include
+#include
+#include
+#include
+#include
+
+inline int64_t MicroProfileTicksPerSecondCpu_()
+{
+ return 1000000000ll;
+}
+
+int64_t MicroProfileTicksPerSecondCpu()
+{
+ return MicroProfileTicksPerSecondCpu_();
+}
+#define MicroProfileTicksPerSecondCpu MicroProfileTicksPerSecondCpu_
+
+inline int64_t MicroProfileGetTick()
+{
+ timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return 1000000000ll * ts.tv_sec + ts.tv_nsec;
+}
+#define MP_TICK() MicroProfileGetTick()
+#define MP_BREAK() __builtin_trap()
+#define MP_THREAD_LOCAL __thread
+#define MP_STRCASECMP strcasecmp
+#define MP_GETCURRENTTHREADID() (uint64_t) pthread_self()
+#define MP_STRCASESTR strcasestr
+#define MP_THREAD_LOCAL __thread
+#define MP_NOINLINE __attribute__((noinline))
+
+void* MicroProfileAllocAligned(size_t nSize, size_t nAlign)
+{
+#if defined(__linux__)
+ void* p;
+ int result = posix_memalign(&p, nAlign, nSize);
+ if(result != 0)
+ {
+ return nullptr;
+ }
+ return p;
+#else
+ return memalign(nAlign, nSize);
+#endif
+}
+void MicroProfileFreeAligned(void* pMem)
+{
+ free(pMem);
+}
+#endif
+
+#endif
+
+#ifdef MICROPROFILE_PS4
+#define MICROPROFILE_PS4_DECL
+#include "microprofile_ps4.h"
+#endif
+
+#ifdef MICROPROFILE_XBOXONE
+#define MICROPROFILE_XBOXONE_DECL
+#include "microprofile_xboxone.h"
+#else
+#ifdef _WIN32
+#include
+#endif
+#endif
+
+#ifdef _WIN32
+typedef uint32_t MicroProfileThreadIdType;
+#else
+#ifdef MICROPROFILE_THREADID_SIZE_4BYTE
+typedef uint32_t MicroProfileThreadIdType;
+#elif MICROPROFILE_THREADID_SIZE_8BYTE
+typedef uint64_t MicroProfileThreadIdType;
+#else
+typedef uint64_t MicroProfileThreadIdType;
+#endif
+#endif
+
+#define MP_ASSERT(a) \
+ do \
+ { \
+ if(!(a)) \
+ { \
+ MP_BREAK(); \
+ } \
+ } while(0)
+
+#ifdef _WIN32
+#include
+typedef UINT_PTR MpSocket;
+#else
+typedef int MpSocket;
+#endif
+
+#ifndef _WIN32
+typedef pthread_t MicroProfileThread;
+#elif defined(_WIN32)
+#if _MSC_VER == 1900
+typedef void* HANDLE;
+#endif
+
+typedef HANDLE MicroProfileThread;
+#else
+typedef std::thread* MicroProfileThread;
+#endif
+
+#if MICROPROFILE_DYNAMIC_INSTRUMENT
+struct MicroProfileSymbolDesc;
+
+#define MICROPROFILE_SUSPEND_MAX (4 << 10)
+struct MicroProfileSuspendState
+{
+ uint32_t SuspendCounter = 0;
+ uint32_t NumSuspended = 0;
+#ifdef _WIN32
+ HANDLE Suspended[MICROPROFILE_SUSPEND_MAX];
+ intptr_t SuspendedIP[MICROPROFILE_SUSPEND_MAX];
+#endif
+};
+
+void MicroProfileSymbolQueryFunctions(MpSocket Connection, const char* pFilter);
+bool MicroProfileInstrumentFunction(void* pFunction, const char* pModuleName, const char* pFunctionName, uint32_t nColor);
+bool MicroProfileSymbolInitialize(bool bStartLoad, const char* pModuleName = 0);
+MicroProfileSymbolDesc* MicroProfileSymbolFindFuction(void* pAddress);
+void MicroProfileInstrumentFunctionsCalled(void* pFunction, const char* pModuleName, const char* pFunctionName, int nMinBytes, int nMaxCalls);
+void MicroProfileSymbolQuerySendResult(MpSocket Connection);
+void MicroProfileSymbolSendFunctionNames(MpSocket Connection);
+void MicroProfileSymbolSendErrors(MpSocket Connection);
+const char* MicroProfileSymbolModuleGetString(uint32_t nIndex);
+void MicroProfileInstrumentWithoutSymbols(const char** pModules, const char** pSymbols, uint32_t nNumSymbols);
+void MicroProfileSymbolUpdateModuleList();
+bool MicroProfileSymInit();
+void MicroProfileSymCleanup();
+#endif
+
+struct MicroProfileFunctionQuery;
+
+// hash table functions & declarations
+struct MicroProfileHashTable;
+struct MicroProfileHashTableIterator;
+typedef bool (*MicroProfileHashCompareFunction)(uint64_t l, uint64_t r);
+typedef uint64_t (*MicroProfileHashFunction)(uint64_t p);
+uint64_t MicroProfileHashTableHashString(uint64_t pString);
+bool MicroProfileHashTableCompareString(uint64_t L, uint64_t R);
+uint64_t MicroProfileHashTableHashPtr(uint64_t pString);
+bool MicroProfileHashTableComparePtr(uint64_t L, uint64_t R);
+void MicroProfileHashTableInit(MicroProfileHashTable* pTable, uint32_t nInitialSize, uint32_t nSearchLimit, MicroProfileHashCompareFunction CompareFunc, MicroProfileHashFunction HashFunc);
+void MicroProfileHashTableDestroy(MicroProfileHashTable* pTable);
+uint64_t MicroProfileHashTableHash(MicroProfileHashTable* pTable, uint64_t K);
+bool MicroProfileHashTableSet(MicroProfileHashTable* pTable, uint64_t Key, uintptr_t Value);
+MicroProfileHashTableIterator MicroProfileGetHashTableIteratorBegin(MicroProfileHashTable* HashTable);
+MicroProfileHashTableIterator MicroProfileGetHashTableIteratorEnd(MicroProfileHashTable* HashTable);
+
+template
+struct MicroProfileArray
+{
+ T* Data = nullptr;
+ uint32_t Size = 0;
+ uint32_t Capacity = 0;
+ T& operator[](const uint32_t Index);
+ const T& operator[](const uint32_t Index) const;
+ T* begin();
+ T* end();
+};
+
+template
+void MicroProfileArrayInit(MicroProfileArray& Array, uint32_t InitialCapacity);
+template
+void MicroProfileArrayDestroy(MicroProfileArray& Array, uint32_t InitialCapacity);
+template
+void MicroProfileArrayClear(MicroProfileArray& Array);
+template
+void MicroProfileArrayPushBack(MicroProfileArray& Array, const T& v);
+
+struct MicroProfileTimer
+{
+ uint64_t nTicks;
+ uint32_t nCount;
+};
+
+struct MicroProfileCategory
+{
+ char pName[MICROPROFILE_NAME_MAX_LEN];
+ uint32_t nGroupMask[MICROPROFILE_MAX_GROUP_INTS];
+};
+
+struct MicroProfileGroupInfo
+{
+ char pName[MICROPROFILE_NAME_MAX_LEN];
+ uint32_t nNameLen;
+ uint32_t nGroupIndex;
+ uint32_t nNumTimers;
+ uint32_t nMaxTimerNameLen;
+ uint32_t nColor;
+ uint32_t nCategory;
+ MicroProfileTokenType Type;
+ int nWSNext;
+};
+
+struct MicroProfileTimerInfo
+{
+ MicroProfileToken nToken;
+ uint32_t nTimerIndex;
+ uint32_t nGroupIndex;
+ char pName[MICROPROFILE_NAME_MAX_LEN];
+ char pNameExt[MICROPROFILE_NAME_MAX_LEN];
+ uint32_t nNameLen;
+ uint32_t nColor;
+ int nWSNext;
+ bool bGraph;
+ MicroProfileTokenType Type;
+ uint32_t Flags;
+};
+
+struct MicroProfileCounterInfo
+{
+ int nParent;
+ int nSibling;
+ int nFirstChild;
+ uint16_t nNameLen;
+ uint8_t nLevel;
+ const char* pName;
+ uint32_t nFlags;
+ int64_t nLimit;
+ double dLimit;
+ int nWSNext;
+ MicroProfileCounterFormat eFormat;
+ std::atomic ExternalAtomic;
+};
+
+struct MicroProfileCounterHistory
+{
+ uint32_t nPut;
+ uint64_t nHistory[MICROPROFILE_GRAPH_HISTORY];
+};
+
+struct MicroProfileCounterSource
+{
+ void* pSource;
+ uint32_t nSourceSize;
+};
+
+struct MicroProfileGraphState
+{
+ int64_t nHistory[MICROPROFILE_GRAPH_HISTORY];
+ MicroProfileToken nToken;
+ int32_t nKey;
+};
+
+struct MicroProfileContextSwitch
+{
+ MicroProfileThreadIdType nThreadOut;
+ MicroProfileThreadIdType nThreadIn;
+ int64_t nCpu : 8;
+ int64_t nTicks : 56;
+};
+
+struct MicroProfileFrameState
+{
+ uint64_t nFrameStartCpu;
+ uint64_t nFrameStartGpu;
+ uint64_t nFrameId;
+ uint32_t nGpuPending;
+ uint32_t nLogStart[MICROPROFILE_MAX_THREADS];
+ uint32_t nLogStartTimeline;
+ uint32_t nTimelineFrameMax;
+ int32_t nHistoryTimeline;
+};
+
+// All frame counter data stored. Used to store the time for all counters/groups for every frame.
+// Must be enabled with MicroProfileEnableFrameCounterExtraData()
+// Will allocate sizeof(MicroProfileFrameExtraCounterData) * MICROPROFILE_MAX_FRAME_HISTORY bytes
+struct MicroProfileFrameExtraCounterData
+{
+ uint16_t NumTimers;
+ uint16_t NumGroups;
+ uint64_t Timers[MICROPROFILE_MAX_TIMERS];
+ uint64_t Groups[MICROPROFILE_MAX_GROUPS];
+};
+
+struct MicroProfileCsvConfig
+{
+ enum CsvConfigState
+ {
+ INACTIVE = 0,
+ CONFIG,
+ ACTIVE,
+ };
+ CsvConfigState State;
+ uint32_t NumTimers;
+ uint32_t NumGroups;
+ uint32_t NumCounters;
+ uint32_t MaxTimers;
+ uint32_t MaxGroups;
+ uint32_t MaxCounters;
+ uint32_t TotalElements;
+ uint16_t* TimerIndices;
+ uint16_t* GroupIndices;
+ uint16_t* CounterIndices;
+ uint64_t* FrameData;
+ const char** pTimerNames;
+ const char** pGroupNames;
+ const char** pCounterNames;
+ uint32_t Flags;
+};
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable : 4200) // zero-sized struct
+#pragma warning(disable : 4201) // nameless struct/union
+#pragma warning(disable : 4244) // possible loss of data
+#pragma warning(disable : 4100) // unreferenced formal parameter
+#pragma warning(disable : 4091)
+#pragma warning(disable : 4189) // local variable is initialized but not referenced. (for defer local variables)
+#pragma warning(disable : 4456)
+#pragma warning(disable : 4702)
+#endif
+
+struct MicroProfileStringBlock
+{
+ enum
+ {
+ DEFAULT_SIZE = 8192,
+ };
+ MicroProfileStringBlock* pNext;
+ uint32_t nUsed;
+ uint32_t nSize;
+ char Memory[];
+};
+
+struct MicroProfileHashTableEntry
+{
+ uint64_t Key;
+ uint64_t Hash;
+ uintptr_t Value;
+};
+
+struct MicroProfileHashTable
+{
+ MicroProfileHashTableEntry* pEntries;
+ uint32_t nUsed;
+ uint32_t nAllocated;
+ uint32_t nSearchLimit;
+ uint32_t nLim;
+ MicroProfileHashCompareFunction CompareFunc;
+ MicroProfileHashFunction HashFunc;
+};
+
+struct MicroProfileHashTableIterator
+{
+ MicroProfileHashTableIterator(uint32_t nIndex, MicroProfileHashTable* pTable)
+ : nIndex(nIndex)
+ , pTable(pTable)
+ {
+ }
+ MicroProfileHashTableIterator(const MicroProfileHashTableIterator& other)
+ : nIndex(other.nIndex)
+ , pTable(other.pTable)
+ {
+ }
+
+ uint32_t nIndex;
+ MicroProfileHashTable* pTable;
+
+ void AssertValid()
+ {
+ MP_ASSERT(nIndex < pTable->nAllocated);
+ }
+
+ MicroProfileHashTableEntry& operator*()
+ {
+ AssertValid();
+ return pTable->pEntries[nIndex];
+ }
+ MicroProfileHashTableEntry* operator->()
+ {
+ AssertValid();
+ return &pTable->pEntries[nIndex];
+ }
+ bool operator==(const MicroProfileHashTableIterator& rhs)
+ {
+ return nIndex == rhs.nIndex && pTable == rhs.pTable;
+ }
+ bool operator!=(const MicroProfileHashTableIterator& rhs)
+ {
+ return nIndex != rhs.nIndex || pTable != rhs.pTable;
+ }
+
+ void SkipInvalid()
+ {
+ while(nIndex < pTable->nAllocated && pTable->pEntries[nIndex].Hash == 0)
+ nIndex++;
+ }
+ MicroProfileHashTableIterator operator++()
+ {
+ AssertValid();
+ nIndex++;
+ SkipInvalid();
+ return *this;
+ }
+ MicroProfileHashTableIterator operator++(int)
+ {
+ MicroProfileHashTableIterator tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+};
+
+struct MicroProfileStrings
+{
+ MicroProfileHashTable HashTable;
+ MicroProfileStringBlock* pFirst;
+ MicroProfileStringBlock* pLast;
+};
+
+struct MicroProfileThreadLog
+{
+
+ std::atomic nPut;
+ std::atomic nGet;
+
+ MicroProfileLogEntry Log[MICROPROFILE_BUFFER_SIZE];
+
+ uint32_t nStackPut;
+ uint32_t nStackScope;
+#ifdef MICROPROFILE_VERIFY_BALANCED
+ uint64_t VerifyStack[MICROPROFILE_STACK_MAX];
+#endif
+ MicroProfileScopeStateC ScopeState[MICROPROFILE_STACK_MAX];
+
+ uint32_t nActive;
+ uint32_t nGpu;
+ MicroProfileThreadIdType nThreadId;
+ uint32_t nLogIndex;
+ uint32_t nCustomId;
+ uint32_t nIdleFrames;
+
+ MicroProfileLogEntry nStackLogEntry[MICROPROFILE_STACK_MAX];
+ uint64_t nChildTickStack[MICROPROFILE_STACK_MAX + 1];
+ int32_t nStackPos;
+
+ uint8_t nGroupStackPos[MICROPROFILE_MAX_GROUPS];
+ uint64_t nGroupTicks[MICROPROFILE_MAX_GROUPS];
+ uint64_t nAggregateGroupTicks[MICROPROFILE_MAX_GROUPS];
+ enum
+ {
+ THREAD_MAX_LEN = 64,
+ };
+ char ThreadName[64];
+ int nFreeListNext;
+};
+
+struct MicroProfileWebSocketBuffer
+{
+ char* pBufferAllocation;
+ char* pBuffer;
+ uint32_t nBufferSize;
+ uint32_t nPut;
+ MpSocket Socket;
+
+ char SendBuffer[MICROPROFILE_WEBSOCKET_BUFFER_SIZE];
+ std::atomic nSendPut;
+ std::atomic nSendGet;
+};
+
+typedef void (*MicroProfileHookFunc)(int x);
+
+struct MicroProfilePatchError
+{
+ unsigned char Code[32];
+ char Message[256];
+ int AlreadyInstrumented;
+ int nCodeSize;
+};
+
+// linear, per-frame per-thread gpu log
+struct MicroProfileThreadLogGpu
+{
+ MicroProfileLogEntry Log[MICROPROFILE_GPU_BUFFER_SIZE];
+ uint32_t nPut;
+ uint32_t nStart;
+ uint32_t nId;
+ void* pContext;
+ uint32_t nAllocated;
+
+ uint32_t nStackScope;
+ MicroProfileScopeStateC ScopeState[MICROPROFILE_STACK_MAX];
+};
+
+#if MICROPROFILE_GPU_TIMERS
+static MicroProfileGpuInsertTimeStamp_CB MicroProfileGpuInsertTimeStamp_Callback = 0;
+static MicroProfileGpuGetTimeStamp_CB MicroProfileGpuGetTimeStamp_Callback = 0;
+static MicroProfileTicksPerSecondGpu_CB MicroProfileTicksPerSecondGpu_Callback = 0;
+static MicroProfileGetGpuTickReference_CB MicroProfileGetGpuTickReference_Callback = 0;
+static MicroProfileGpuFlip_CB MicroProfileGpuFlip_Callback = 0;
+static MicroProfileGpuShutdown_CB MicroProfileGpuShutdown_Callback = 0;
+
+uint32_t MicroProfileGpuInsertTimeStamp(void* pContext)
+{
+ return MicroProfileGpuInsertTimeStamp_Callback ? MicroProfileGpuInsertTimeStamp_Callback(pContext) : 0;
+}
+uint64_t MicroProfileGpuGetTimeStamp(uint32_t nKey)
+{
+ return MicroProfileGpuGetTimeStamp_Callback ? MicroProfileGpuGetTimeStamp_Callback(nKey) : 1;
+}
+uint64_t MicroProfileTicksPerSecondGpu()
+{
+ return MicroProfileTicksPerSecondGpu_Callback ? MicroProfileTicksPerSecondGpu_Callback() : 1;
+}
+int MicroProfileGetGpuTickReference(int64_t* pOutCPU, int64_t* pOutGpu)
+{
+ return MicroProfileGetGpuTickReference_Callback ? MicroProfileGetGpuTickReference_Callback(pOutCPU, pOutGpu) : 0;
+}
+uint32_t MicroProfileGpuFlip(void* p)
+{
+ return MicroProfileGpuFlip_Callback ? MicroProfileGpuFlip_Callback(p) : 0;
+}
+void MicroProfileGpuShutdown()
+{
+ if(MicroProfileGpuShutdown_Callback)
+ MicroProfileGpuShutdown_Callback();
+}
+
+#endif
+
+#if MICROPROFILE_GPU_TIMERS_D3D11
+//:'######:::'########::'##::::'##::::'########:::'#######::'########:::::'##::::::'##:::
+//'##... ##:: ##.... ##: ##:::: ##:::: ##.... ##:'##.... ##: ##.... ##::'####::::'####:::
+// ##:::..::: ##:::: ##: ##:::: ##:::: ##:::: ##:..::::: ##: ##:::: ##::.. ##::::.. ##:::
+// ##::'####: ########:: ##:::: ##:::: ##:::: ##::'#######:: ##:::: ##:::: ##:::::: ##:::
+// ##::: ##:: ##.....::: ##:::: ##:::: ##:::: ##::...... ##: ##:::: ##:::: ##:::::: ##:::
+// ##::: ##:: ##:::::::: ##:::: ##:::: ##:::: ##:'##:::: ##: ##:::: ##:::: ##:::::: ##:::
+//. ######::: ##::::::::. #######::::: ########::. #######:: ########:::'######::'######:
+//:......::::..::::::::::.......::::::........::::.......:::........::::......:::......::
+
+struct MicroProfileD3D11Frame
+{
+ uint32_t m_nQueryStart;
+ uint32_t m_nQueryCountMax;
+ std::atomic m_nQueryCount;
+ uint32_t m_nRateQueryStarted;
+ void* m_pRateQuery;
+};
+
+struct MicroProfileGpuTimerStateD3D11 : public MicroProfileGpuTimerState
+{
+ uint32_t bInitialized;
+ void* m_pDevice;
+ void* m_pImmediateContext;
+ void* m_pQueries[MICROPROFILE_D3D11_MAX_QUERIES];
+ int64_t m_nQueryResults[MICROPROFILE_D3D11_MAX_QUERIES];
+
+ uint32_t m_nQueryPut;
+ uint32_t m_nQueryGet;
+ uint32_t m_nQueryFrame;
+ int64_t m_nQueryFrequency;
+ void* pSyncQuery;
+
+ MicroProfileD3D11Frame m_QueryFrames[MICROPROFILE_GPU_FRAME_DELAY];
+};
+
+uint32_t MicroProfileGpuInsertTimeStampD3D11(void* pContext_);
+uint64_t MicroProfileGpuGetTimeStampD3D11(uint32_t nIndex);
+bool MicroProfileGpuGetDataD3D11(void* pQuery, void* pData, uint32_t nDataSize);
+uint64_t MicroProfileTicksPerSecondGpuD3D11();
+uint32_t MicroProfileGpuFlipD3D11(void* pDeviceContext_);
+void MicroProfileGpuInitD3D11(void* pDevice_, void* pImmediateContext);
+void MicroProfileGpuShutdownD3D11();
+int MicroProfileGetGpuTickReferenceD3D11(int64_t* pOutCPU, int64_t* pOutGpu);
+MicroProfileGpuTimerStateD3D11* MicroProfileGetGpuTimerStateD3D11();
+#endif
+
+#if MICROPROFILE_GPU_TIMERS_D3D12
+//:'######:::'########::'##::::'##::::'########:::'#######::'########:::::'##::::'#######::
+//'##... ##:: ##.... ##: ##:::: ##:::: ##.... ##:'##.... ##: ##.... ##::'####:::'##.... ##:
+// ##:::..::: ##:::: ##: ##:::: ##:::: ##:::: ##:..::::: ##: ##:::: ##::.. ##:::..::::: ##:
+// ##::'####: ########:: ##:::: ##:::: ##:::: ##::'#######:: ##:::: ##:::: ##::::'#######::
+// ##::: ##:: ##.....::: ##:::: ##:::: ##:::: ##::...... ##: ##:::: ##:::: ##:::'##::::::::
+// ##::: ##:: ##:::::::: ##:::: ##:::: ##:::: ##:'##:::: ##: ##:::: ##:::: ##::: ##::::::::
+//. ######::: ##::::::::. #######::::: ########::. #######:: ########:::'######: #########:
+//:......::::..::::::::::.......::::::........::::.......:::........::::......::.........::
+
+#include
+
+#ifndef MICROPROFILE_D3D12_MAX_QUERIES
+#define MICROPROFILE_D3D12_MAX_QUERIES (32 << 10)
+#endif
+
+#define MICROPROFILE_D3D_MAX_NODE_COUNT 4
+#define MICROPROFILE_D3D_INTERNAL_DELAY 8
+
+#define MP_NODE_MASK_ALL(n) ((1u << (n)) - 1u)
+#define MP_NODE_MASK_ONE(n) (1u << (n))
+
+struct MicroProfileGpuTimerStateD3D12;
+
+int MicroProfileGetGpuTickReferenceD3D12(int64_t* pOutCPU, int64_t* pOutGpu);
+uint32_t MicroProfileGpuInsertTimeStampD3D12(void* pContext);
+uint64_t MicroProfileGpuGetTimeStampD3D12(uint32_t nIndex);
+uint64_t MicroProfileTicksPerSecondGpuD3D12();
+uint32_t MicroProfileGpuFlipD3D12(void* pContext);
+void MicroProfileGpuInitD3D12(void* pDevice_, uint32_t nNodeCount, void** pCommandQueues_, void** pCommandQueuesCopy_);
+void MicroProfileGpuShutdownD3D12();
+void MicroProfileSetCurrentNodeD3D12(uint32_t nNode);
+int MicroProfileGetGpuTickReferenceD3D12(int64_t* pOutCPU, int64_t* pOutGpu);
+MicroProfileGpuTimerStateD3D12* MicroProfileGetGpuTimerStateD3D12();
+
+struct MicroProfileFrameD3D12
+{
+ uint32_t nTimeStampBegin;
+ uint32_t nTimeStampCount;
+ uint32_t nTimeStampBeginCopyQueue;
+ uint32_t nTimeStampCountCopyQueue;
+ uint32_t nNode;
+ ID3D12GraphicsCommandList* pCommandList[MICROPROFILE_D3D_MAX_NODE_COUNT];
+ ID3D12GraphicsCommandList* pCommandListCopy[MICROPROFILE_D3D_MAX_NODE_COUNT];
+ ID3D12CommandAllocator* pCommandAllocator;
+ ID3D12CommandAllocator* pCommandAllocatorCopy;
+};
+
+struct MicroProfileGpuTimerStateD3D12 : public MicroProfileGpuTimerState
+{
+ ID3D12Device* pDevice;
+ uint32_t nNodeCount;
+ uint32_t nCurrentNode;
+
+ uint64_t nFrame;
+ uint64_t nPendingFrame;
+
+ uint32_t nFrameStartTimeStamps;
+ uint32_t nFrameStartCopyQueueTimeStamps;
+ std::atomic nFrameCountTimeStamps;
+ std::atomic nFrameCountCopyQueueTimeStamps;
+
+ int64_t nFrequency;
+ ID3D12Resource* pBuffer;
+ ID3D12Resource* pBufferCopy;
+
+ struct
+ {
+ ID3D12CommandQueue* pCommandQueue;
+ ID3D12CommandQueue* pCommandQueueCopy;
+ ID3D12QueryHeap* pHeap;
+ ID3D12QueryHeap* pCopyQueueHeap;
+ ID3D12Fence* pFence;
+ ID3D12Fence* pFenceCopy;
+ } NodeState[MICROPROFILE_D3D_MAX_NODE_COUNT];
+
+ uint16_t nQueryFrames[MICROPROFILE_D3D12_MAX_QUERIES];
+ int64_t nResults[MICROPROFILE_D3D12_MAX_QUERIES];
+ uint16_t nQueryFramesCopy[MICROPROFILE_D3D12_MAX_QUERIES];
+ int64_t nResultsCopy[MICROPROFILE_D3D12_MAX_QUERIES];
+
+ MicroProfileFrameD3D12 Frames[MICROPROFILE_D3D_INTERNAL_DELAY];
+};
+#endif
+
+#if MICROPROFILE_GPU_TIMERS_GL
+//:'######:::'########::'##::::'##:::::'######:::'##:::::::
+//'##... ##:: ##.... ##: ##:::: ##::::'##... ##:: ##:::::::
+// ##:::..::: ##:::: ##: ##:::: ##:::: ##:::..::: ##:::::::
+// ##::'####: ########:: ##:::: ##:::: ##::'####: ##:::::::
+// ##::: ##:: ##.....::: ##:::: ##:::: ##::: ##:: ##:::::::
+// ##::: ##:: ##:::::::: ##:::: ##:::: ##::: ##:: ##:::::::
+//. ######::: ##::::::::. #######:::::. ######::: ########:
+//:......::::..::::::::::.......:::::::......::::........::
+struct MicroProfileGpuTimerStateGL : public MicroProfileGpuTimerState
+{
+ uint32_t GLTimers[MICROPROFILE_GL_MAX_QUERIES];
+ uint32_t GLTimerPos;
+};
+
+MicroProfileGpuTimerStateGL* MicroProfileGetGpuTimerStateGL();
+uint32_t MicroProfileGpuInsertTimeStampGL(void* pContext);
+uint64_t MicroProfileGpuGetTimeStampGL(uint32_t nKey);
+uint64_t MicroProfileTicksPerSecondGpuGL();
+int MicroProfileGetGpuTickReferenceGL(int64_t* pOutCpu, int64_t* pOutGpu);
+uint32_t MicroProfileGpuFlipGL(void* pContext);
+void MicroProfileGpuShutdownGL();
+#endif
+
+#if MICROPROFILE_GPU_TIMERS_VULKAN
+
+//:'######:::'########::'##::::'##::::'##::::'##:'##::::'##:'##:::::::'##:::'##::::'###::::'##::: ##:
+//'##... ##:: ##.... ##: ##:::: ##:::: ##:::: ##: ##:::: ##: ##::::::: ##::'##::::'## ##::: ###:: ##:
+// ##:::..::: ##:::: ##: ##:::: ##:::: ##:::: ##: ##:::: ##: ##::::::: ##:'##::::'##:. ##:: ####: ##:
+// ##::'####: ########:: ##:::: ##:::: ##:::: ##: ##:::: ##: ##::::::: #####::::'##:::. ##: ## ## ##:
+// ##::: ##:: ##.....::: ##:::: ##::::. ##:: ##:: ##:::: ##: ##::::::: ##. ##::: #########: ##. ####:
+// ##::: ##:: ##:::::::: ##:::: ##:::::. ## ##::: ##:::: ##: ##::::::: ##:. ##:: ##.... ##: ##:. ###:
+//. ######::: ##::::::::. #######:::::::. ###::::. #######:: ########: ##::. ##: ##:::: ##: ##::. ##:
+//:......::::..::::::::::.......:::::::::...::::::.......:::........::..::::..::..:::::..::..::::..::
+
+struct MicroProfileGpuTimerStateVulkan;
+MicroProfileGpuTimerStateVulkan* MicroProfileGetGpuTimerStateVulkan();
+uint32_t MicroProfileGpuInsertTimeStampVulkan(void* pContext);
+uint64_t MicroProfileGpuGetTimeStampVulkan(uint32_t nKey);
+uint64_t MicroProfileTicksPerSecondGpuVulkan();
+int MicroProfileGetGpuTickReferenceVulkan(int64_t* pOutCpu, int64_t* pOutGpu);
+uint32_t MicroProfileGpuFlipVulkan(void* pContext);
+void MicroProfileGpuShutdownVulkan();
+#endif
+
+struct MicroProfileSymbolState
+{
+ std::atomic nModuleLoadsFinished;
+ std::atomic nModuleLoadsRequested;
+ std::atomic nSymbolsLoaded;
+};
+
+struct MicroProfileSymbolModuleRegion
+{
+ intptr_t nBegin;
+ intptr_t nEnd;
+};
+struct MicroProfileSymbolModule
+{
+ uint64_t nModuleBase;
+ uint32_t nMatchOffset;
+ uint32_t nStringOffset;
+ const char* pBaseString;
+ const char* pTrimmedString;
+ MicroProfileSymbolModuleRegion Regions[MICROPROFILE_MAX_MODULE_EXEC_REGIONS];
+ int nNumExecutableRegions;
+
+ bool bDownloading;
+ intptr_t nProgress;
+ intptr_t nProgressTarget;
+ struct MicroProfileSymbolBlock* pSymbolBlock;
+ MicroProfileHashTable AddressToSymbol;
+
+ int64_t nSymbols;
+ std::atomic nSymbolsLoaded;
+ std::atomic nModuleLoadRequested;
+ std::atomic nModuleLoadFinished;
+};
+
+struct MicroProfileInstrumentMemoryRegion
+{
+ intptr_t Start;
+ intptr_t Size;
+ uint32_t Protect;
+};
+
+struct MicroProfile
+{
+ uint32_t nTotalTimers;
+ uint32_t nGroupCount;
+ uint32_t nCategoryCount;
+ uint32_t nAggregateClear;
+ uint32_t nAggregateFlip;
+ uint32_t nAggregateFlipCount;
+ uint32_t nAggregateFrames;
+
+ uint64_t nFlipStartTick;
+ uint64_t nAggregateFlipTick;
+
+ uint32_t nDisplay;
+ uint32_t nBars;
+ uint32_t nActiveGroups[MICROPROFILE_MAX_GROUP_INTS];
+ bool AnyActive;
+ uint32_t nFrozen;
+ uint32_t nWasFrozen;
+ uint32_t nPlatformMarkersEnabled;
+
+ uint32_t nForceEnable;
+
+ uint32_t nForceGroups[MICROPROFILE_MAX_GROUP_INTS];
+ uint32_t nActiveGroupsWanted[MICROPROFILE_MAX_GROUP_INTS];
+ uint32_t nGroupMask[MICROPROFILE_MAX_GROUP_INTS];
+
+ uint32_t nStartEnabled;
+ uint32_t nAllThreadsWanted;
+
+ uint32_t nOverflow;
+
+ uint32_t nMaxGroupSize;
+ uint32_t nDumpFileNextFrame;
+ uint32_t nDumpFileCountDown;
+ uint32_t nDumpSpikeMask;
+ uint32_t nAutoClearFrames;
+
+ float fDumpCpuSpike;
+ float fDumpGpuSpike;
+ char HtmlDumpPath[512];
+ char CsvDumpPath[512];
+ uint32_t DumpFrameCount;
+
+ int64_t nPauseTicks;
+ std::atomic nContextSwitchStalledTick;
+ int64_t nContextSwitchLastPushed;
+ int64_t nContextSwitchLastIndexPushed;
+
+ float fReferenceTime;
+ float fRcpReferenceTime;
+
+ MicroProfileCategory CategoryInfo[MICROPROFILE_MAX_CATEGORIES];
+ MicroProfileGroupInfo GroupInfo[MICROPROFILE_MAX_GROUPS];
+ MicroProfileTimerInfo TimerInfo[MICROPROFILE_MAX_TIMERS];
+ uint32_t TimerToGroup[MICROPROFILE_MAX_TIMERS];
+
+ MicroProfileTimer AccumTimers[MICROPROFILE_MAX_TIMERS];
+ uint64_t AccumMaxTimers[MICROPROFILE_MAX_TIMERS];
+ uint64_t AccumMinTimers[MICROPROFILE_MAX_TIMERS];
+ uint64_t AccumTimersExclusive[MICROPROFILE_MAX_TIMERS];
+ uint64_t AccumMaxTimersExclusive[MICROPROFILE_MAX_TIMERS];
+
+ MicroProfileTimer Frame[MICROPROFILE_MAX_TIMERS];
+ uint64_t FrameExclusive[MICROPROFILE_MAX_TIMERS];
+
+ MicroProfileTimer Aggregate[MICROPROFILE_MAX_TIMERS];
+ uint64_t AggregateMax[MICROPROFILE_MAX_TIMERS];
+ uint64_t AggregateMin[MICROPROFILE_MAX_TIMERS];
+ uint64_t AggregateExclusive[MICROPROFILE_MAX_TIMERS];
+ uint64_t AggregateMaxExclusive[MICROPROFILE_MAX_TIMERS];
+
+ uint32_t FrameGroupThreadValid[MICROPROFILE_MAX_THREADS / 32 + 1];
+ struct GroupTime
+ {
+ uint64_t nTicks;
+ uint64_t nTicksExclusive;
+ uint32_t nCount;
+ };
+
+ GroupTime FrameGroupThread[MICROPROFILE_MAX_THREADS][MICROPROFILE_MAX_GROUPS];
+ GroupTime FrameGroup[MICROPROFILE_MAX_GROUPS];
+ uint64_t AccumGroup[MICROPROFILE_MAX_GROUPS];
+ uint64_t AccumGroupMax[MICROPROFILE_MAX_GROUPS];
+
+ uint64_t AggregateGroup[MICROPROFILE_MAX_GROUPS];
+ uint64_t AggregateGroupMax[MICROPROFILE_MAX_GROUPS];
+
+ MicroProfileGraphState Graph[MICROPROFILE_MAX_GRAPHS];
+ uint32_t nGraphPut;
+
+ uint32_t nThreadActive[MICROPROFILE_MAX_THREADS];
+ MicroProfileThreadLog* Pool[MICROPROFILE_MAX_THREADS];
+ MicroProfileThreadLogGpu* PoolGpu[MICROPROFILE_MAX_THREADS];
+
+ MicroProfileThreadLog TimelineLog;
+ uint32_t TimelineTokenFrameEnter[MICROPROFILE_TIMELINE_MAX_TOKENS];
+ uint32_t TimelineTokenFrameLeave[MICROPROFILE_TIMELINE_MAX_TOKENS];
+ uint32_t TimelineToken[MICROPROFILE_TIMELINE_MAX_TOKENS];
+ const char* TimelineTokenStaticString[MICROPROFILE_TIMELINE_MAX_TOKENS];
+
+ uint32_t nTimelineFrameMax;
+ MicroProfileFrameExtraCounterData* FrameExtraCounterData;
+ MicroProfileCsvConfig CsvConfig;
+ const char* pSettings;
+ const char* pSettingsReadOnly;
+ const char* pSettingsTemp;
+
+ uint32_t nNumLogs;
+ uint32_t nNumLogsGpu;
+ uint32_t nMemUsage;
+ int nFreeListHead;
+
+ uint32_t nFrameCurrent;
+ uint32_t nFrameCurrentIndex;
+ uint32_t nFramePut;
+ uint32_t nFrameNext;
+ uint64_t nFramePutIndex;
+
+ MicroProfileFrameState Frames[MICROPROFILE_MAX_FRAME_HISTORY];
+
+ uint64_t nFlipTicks;
+ uint64_t nFlipAggregate;
+ uint64_t nFlipMax;
+ uint64_t nFlipAggregateDisplay;
+ uint64_t nFlipMaxDisplay;
+
+ MicroProfileThread ContextSwitchThread;
+ bool bContextSwitchRunning;
+ bool bContextSwitchStop;
+ bool bContextSwitchAllThreads;
+ bool bContextSwitchNoBars;
+ uint32_t nContextSwitchUsage;
+ uint32_t nContextSwitchLastPut;
+
+ int64_t nContextSwitchHoverTickIn;
+ int64_t nContextSwitchHoverTickOut;
+ uint32_t nContextSwitchHoverThread;
+ uint32_t nContextSwitchHoverThreadBefore;
+ uint32_t nContextSwitchHoverThreadAfter;
+ uint8_t nContextSwitchHoverCpu;
+ uint8_t nContextSwitchHoverCpuNext;
+
+ uint32_t CoreCount;
+ uint8_t CoreEfficiencyClass[MICROPROFILE_MAX_CPU_CORES];
+
+ uint32_t nContextSwitchPut;
+ MicroProfileContextSwitch ContextSwitch[MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE];
+
+ MpSocket ListenerSocket;
+ uint32_t nWebServerPort;
+
+ char WebServerBuffer[MICROPROFILE_WEBSERVER_SOCKET_BUFFER_SIZE];
+ uint32_t WebServerPut;
+
+ uint64_t nWebServerDataSent;
+
+ int WebSocketTimers;
+ int WebSocketCounters;
+ int WebSocketGroups;
+ uint32_t nWebSocketDirty;
+ MpSocket WebSockets[1];
+ int64_t WebSocketFrameLast[1];
+ uint32_t nNumWebSockets;
+ uint32_t nSocketFail; // for error propagation.
+
+ MicroProfileThread WebSocketSendThread;
+ bool WebSocketThreadRunning;
+ bool WebSocketThreadJoined;
+
+ uint32_t WSCategoriesSent;
+ uint32_t WSGroupsSent;
+ uint32_t WSTimersSent;
+ uint32_t WSCountersSent;
+ MicroProfileWebSocketBuffer WSBuf;
+ char* pJsonSettings;
+ const char* pJsonSettingsName;
+ bool bJsonSettingsReadOnly;
+ uint32_t nJsonSettingsPending;
+ uint32_t nJsonSettingsBufferSize;
+ uint32_t nWSWasConnected;
+ uint32_t nMicroProfileShutdown;
+ uint32_t nWSViewMode;
+
+ char CounterNames[MICROPROFILE_MAX_COUNTER_NAME_CHARS];
+ MicroProfileCounterInfo CounterInfo[MICROPROFILE_MAX_COUNTERS];
+ MicroProfileCounterSource CounterSource[MICROPROFILE_MAX_COUNTERS];
+ uint32_t nNumCounters;
+ uint32_t nCounterNamePos;
+ std::atomic Counters[MICROPROFILE_MAX_COUNTERS];
+ std::atomic* CountersDouble;
+#if MICROPROFILE_COUNTER_HISTORY // uses 1kb per allocated counter. 512kb for default counter count
+ uint32_t nCounterHistoryPut;
+ int64_t nCounterHistory[MICROPROFILE_GRAPH_HISTORY][MICROPROFILE_MAX_COUNTERS]; // flipped to make swapping cheap, drawing more expensive.
+ int64_t nCounterMax[MICROPROFILE_MAX_COUNTERS];
+ int64_t nCounterMin[MICROPROFILE_MAX_COUNTERS];
+ double* dCounterHistory;
+ double* dCounterMax;
+ double* dCounterMin;
+#endif
+
+ MicroProfileThread AutoFlipThread;
+ std::atomic nAutoFlipDelay;
+ std::atomic nAutoFlipStop;
+
+ MicroProfileStrings Strings;
+ MicroProfileToken CounterToken_MicroProfile;
+ MicroProfileToken CounterToken_StringBlock;
+ MicroProfileToken CounterToken_StringBlock_Count;
+ MicroProfileToken CounterToken_StringBlock_Waste;
+ MicroProfileToken CounterToken_StringBlock_Strings;
+ MicroProfileToken CounterToken_StringBlock_Memory;
+
+ MicroProfileToken CounterToken_Alloc;
+ MicroProfileToken CounterToken_Alloc_Memory;
+ MicroProfileToken CounterToken_Alloc_Count;
+
+#if MICROPROFILE_DYNAMIC_INSTRUMENT
+ uint32_t DynamicTokenIndex;
+ MicroProfileToken DynamicTokens[MICROPROFILE_MAX_DYNAMIC_TOKENS];
+ void* FunctionsInstrumented[MICROPROFILE_MAX_DYNAMIC_TOKENS];
+ const char* FunctionsInstrumentedName[MICROPROFILE_MAX_DYNAMIC_TOKENS];
+ const char* FunctionsInstrumentedModuleNames[MICROPROFILE_MAX_DYNAMIC_TOKENS];
+ // const char* FunctionsInstrumentedUnmangled[MICROPROFILE_MAX_DYNAMIC_TOKENS];
+ uint32_t WSFunctionsInstrumentedSent;
+ MicroProfileSymbolState SymbolState;
+
+ MicroProfileSymbolModule SymbolModules[MICROPROFILE_INSTRUMENT_MAX_MODULES];
+ char SymbolModuleNameBuffer[MICROPROFILE_INSTRUMENT_MAX_MODULE_CHARS];
+ int SymbolModuleNameOffset;
+ int SymbolNumModules;
+ int WSSymbolModulesSent;
+ std::atomic nSymbolsDirty;
+
+ MicroProfileFunctionQuery* pPendingQuery;
+ MicroProfileFunctionQuery* pFinishedQuery;
+ MicroProfileFunctionQuery* pQueryFreeList;
+ uint32_t nQueryProcessed;
+ uint32_t nNumQueryFree;
+ uint32_t nNumQueryAllocated;
+
+ int SymbolThreadRunning;
+ int SymbolThreadFinished;
+ MicroProfileThread SymbolThread;
+ int nNumPatchErrors;
+ MicroProfilePatchError PatchErrors[MICROPROFILE_MAX_PATCH_ERRORS];
+ int nNumPatchErrorFunctions;
+ const char* PatchErrorFunctionNames[MICROPROFILE_MAX_PATCH_ERRORS];
+ MicroProfileSuspendState SuspendState;
+ MicroProfileArray MemoryRegions;
+#endif
+
+ int GpuQueue;
+ MicroProfileThreadLogGpu* pGpuGlobal;
+ MicroProfileGpuTimerState* pGPU;
+};
+
+inline uint32_t MicroProfileLogGetType(MicroProfileLogEntry Index)
+{
+ return ((MP_LOG_BEGIN_MASK & Index) >> 62) & 0x3;
+}
+
+inline uint64_t MicroProfileLogGetTimerIndex(MicroProfileLogEntry Index)
+{
+ return (0x3fff & (Index >> 48));
+}
+uint32_t MicroProfileLogGetDataSize(MicroProfileLogEntry Index)
+{
+ if(MicroProfileLogGetType(Index) == MP_LOG_EXTENDED)
+ return 0xffff & (Index >> 32);
+ else
+ return 0;
+}
+
+inline EMicroProfileTokenExtended MicroProfileLogGetExtendedToken(MicroProfileLogEntry Index)
+{
+ return (EMicroProfileTokenExtended)(0x3fff & (Index >> 48));
+}
+
+inline uint32_t MicroProfileLogGetExtendedDataSize(MicroProfileLogEntry Index)
+{
+ return (uint32_t)(0xffff & (Index >> 32));
+}
+
+inline uint32_t MicroProfileLogGetExtendedPayload(MicroProfileLogEntry Index)
+{
+ return (uint32_t)(0xffffffff & Index);
+}
+
+inline uint64_t MicroProfileLogGetExtendedPayloadNoData(MicroProfileLogEntry Index)
+{
+ return (uint64_t)(MP_LOG_TICK_MASK & Index);
+}
+
+inline void* MicroProfileLogGetExtendedPayloadNoDataPtr(MicroProfileLogEntry Index)
+{
+ return (void*)(MP_LOG_PAYLOAD_PTR_MASK & Index);
+}
+
+MicroProfileLogEntry MicroProfileMakeLogIndex(uint64_t nBegin, MicroProfileToken nToken, int64_t nTick);
+MicroProfileLogEntry MicroProfileMakeLogExtended(EMicroProfileTokenExtended eTokenExt, uint32_t nDataSizeQWords, uint32_t nPayload);
+MicroProfileLogEntry MicroProfileMakeLogExtendedNoData(EMicroProfileTokenExtended eTokenExt, uint64_t nTick);
+
+inline MicroProfileLogEntry MicroProfileMakeLogIndex(uint64_t nBegin, MicroProfileToken nToken, int64_t nTick)
+{
+ MicroProfileLogEntry Entry = (nBegin << 62) | ((0x3fff & nToken) << 48) | (MP_LOG_TICK_MASK & nTick);
+ uint32_t t = MicroProfileLogGetType(Entry);
+ uint64_t nTimerIndex = MicroProfileLogGetTimerIndex(Entry);
+ MP_ASSERT(t == nBegin);
+ MP_ASSERT(nTimerIndex == (nToken & 0x3fff));
+ return Entry;
+}
+
+// extended data, with the option to store 0xfffe * 8 bytes after
+inline MicroProfileLogEntry MicroProfileMakeLogExtended(EMicroProfileTokenExtended eTokenExt, uint32_t nDataSizeQWords, uint32_t nPayload)
+{
+ MP_ASSERT(nDataSizeQWords < 0xffff);
+ MicroProfileLogEntry Entry = (((uint64_t)MP_LOG_EXTENDED) << 62) | ((0x3fff & (uint64_t)eTokenExt) << 48) | ((0xffff & (uint64_t)nDataSizeQWords) << 32) | nPayload;
+
+ MP_ASSERT(MicroProfileLogGetExtendedToken(Entry) == eTokenExt);
+ MP_ASSERT(MicroProfileLogGetExtendedDataSize(Entry) == nDataSizeQWords);
+ MP_ASSERT(MicroProfileLogGetExtendedPayload(Entry) == nPayload);
+
+ return Entry;
+}
+// extended with no data, but instead 48 bits payload
+inline MicroProfileLogEntry MicroProfileMakeLogExtendedNoData(EMicroProfileTokenExtended eTokenExt, uint64_t nPayload)
+{
+ MicroProfileLogEntry Entry = (((uint64_t)MP_LOG_EXTENDED_NO_DATA) << 62) | ((0x3fff & (uint64_t)eTokenExt) << 48) | (MP_LOG_TICK_MASK & nPayload);
+
+ MP_ASSERT(MicroProfileLogGetExtendedToken(Entry) == eTokenExt);
+ MP_ASSERT(MicroProfileLogGetExtendedPayloadNoData(Entry) == nPayload);
+
+ return Entry;
+}
+
+// extended with no data, but instead 61 bits payload. used to store a pointer.
+inline MicroProfileLogEntry MicroProfileMakeLogExtendedNoDataPtr(uint64_t nPayload)
+{
+ uint64_t hest = ETOKEN_CSTR_PTR;
+ MicroProfileLogEntry Entry = (((uint64_t)MP_LOG_EXTENDED_NO_DATA) << 62) | (hest << 48) | (MP_LOG_PAYLOAD_PTR_MASK & nPayload);
+ uint64_t v0 = (MP_LOG_PAYLOAD_PTR_MASK & nPayload);
+ uint64_t v1 = (uint64_t)MicroProfileLogGetExtendedPayloadNoDataPtr(Entry);
+
+ MP_ASSERT(v0 == v1);
+ return Entry;
+}
+
+inline uint32_t MicroProfileGetQWordSize(uint32_t nDataSize)
+{
+ uint32_t nSize = (nDataSize + 7) / 8;
+ MP_ASSERT(nSize < 0xffff); // won't pack...
+ return nSize;
+}
+
+namespace
+{
+struct MicroProfilePayloadPack
+{
+ union
+ {
+ struct
+ {
+#if MICROPROFILE_BIG_ENDIAN /// NOT implemented.
+ char h;
+ char message[7];
+#else
+ char message[7];
+ char h;
+#endif
+ };
+ uint64_t LogEntry;
+ };
+};
+}; // namespace
+
+inline int64_t MicroProfileLogTickDifference(MicroProfileLogEntry Start, MicroProfileLogEntry End)
+{
+ int64_t nStart = Start;
+ int64_t nEnd = End;
+ int64_t nDifference = ((nEnd << 16) - (nStart << 16));
+ return nDifference >> 16;
+}
+inline int64_t MicroProfileLogTickMax(MicroProfileLogEntry A, MicroProfileLogEntry B)
+{
+ int64_t Diff = MicroProfileLogTickDifference(A, B);
+ if(Diff < 0)
+ {
+ return A;
+ }
+ else
+ {
+ return B;
+ }
+}
+
+inline int64_t MicroProfileLogTickMin(MicroProfileLogEntry A, MicroProfileLogEntry B)
+{
+ int64_t Diff = MicroProfileLogTickDifference(A, B);
+ if(Diff < 0)
+ {
+ return B;
+ }
+ else
+ {
+ return A;
+ }
+}
+inline int64_t MicroProfileLogTickClamp(uint64_t T, uint64_t min, uint64_t max)
+{
+ return MicroProfileLogTickMin(MicroProfileLogTickMax(T, min), max);
+}
+
+inline int64_t MicroProfileLogGetTick(MicroProfileLogEntry e)
+{
+ return MP_LOG_TICK_MASK & e;
+}
+
+inline int64_t MicroProfileLogSetTick(MicroProfileLogEntry e, int64_t nTick)
+{
+ return (MP_LOG_TICK_MASK & nTick) | (e & ~MP_LOG_TICK_MASK);
+}
+
+inline uint16_t MicroProfileGetTimerIndex(MicroProfileToken t)
+{
+ return (t & 0xffff);
+}
+inline uint32_t MicroProfileGetGroupMask(MicroProfileToken t)
+{
+ return (uint32_t)((t >> 16) & MICROPROFILE_GROUP_MASK_ALL);
+}
+inline uint32_t MicroProfileGetGroupMaskIndex(MicroProfileToken t)
+{
+ return (uint32_t)(t >> 48);
+}
+
+inline MicroProfileToken MicroProfileMakeToken(uint32_t nGroupMask, uint16_t nGroupIndex, uint16_t nTimer)
+{
+ uint64_t token = ((uint64_t)nGroupIndex << 48llu) | ((uint64_t)nGroupMask << 16llu) | nTimer;
+ if(0 != (token & MP_LOG_CSTR_MASK))
+ {
+ MP_BREAK(); // should never happen
+ }
+ return token;
+}
+
+template
+T MicroProfileMin(T a, T b)
+{
+ return a < b ? a : b;
+}
+
+template
+T MicroProfileMax(T a, T b)
+{
+ return a > b ? a : b;
+}
+template
+T MicroProfileClamp(T a, T min_, T max_)
+{
+ return MicroProfileMin(max_, MicroProfileMax(min_, a));
+}
+
+inline int64_t MicroProfileMsToTick(float fMs, int64_t nTicksPerSecond)
+{
+ return (int64_t)(fMs * 0.001f * nTicksPerSecond);
+}
+
+inline float MicroProfileTickToMsMultiplier(int64_t nTicksPerSecond)
+{
+ return 1000.f / (nTicksPerSecond ? nTicksPerSecond : 1);
+}
+float MicroProfileTickToMsMultiplierCpu()
+{
+ return MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu());
+}
+
+float MicroProfileTickToMsMultiplierGpu()
+{
+ return MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondGpu());
+}
+uint16_t MicroProfileGetGroupIndex(MicroProfileToken t)
+{
+ return (uint16_t)MicroProfileGet()->TimerToGroup[MicroProfileGetTimerIndex(t)];
+}
+
+uint64_t MicroProfileTick()
+{
+ return MP_TICK();
+}
+
+#ifdef _WIN32
+#include
+#define fopen microprofile_fopen_helper
+
+FILE* microprofile_fopen_helper(const char* filename, const char* mode)
+{
+ FILE* F = 0;
+ if(0 == fopen_s(&F, filename, mode))
+ {
+ return F;
+ }
+ return 0;
+}
+
+int64_t MicroProfileTicksPerSecondCpu()
+{
+ static int64_t nTicksPerSecond = 0;
+ if(nTicksPerSecond == 0)
+ {
+ QueryPerformanceFrequency((LARGE_INTEGER*)&nTicksPerSecond);
+ }
+ return nTicksPerSecond;
+}
+int64_t MicroProfileGetTick()
+{
+ int64_t ticks;
+ QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
+ return ticks;
+}
+
+#endif
+
+#if 1
+
+typedef void* (*MicroProfileThreadFunc)(void*);
+
+#ifndef _WIN32
+typedef pthread_t MicroProfileThread;
+void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
+{
+ pthread_attr_t Attr;
+ int r = pthread_attr_init(&Attr);
+ MP_ASSERT(r == 0);
+ pthread_create(pThread, &Attr, Func, 0);
+}
+void MicroProfileThreadJoin(MicroProfileThread* pThread)
+{
+ int r = pthread_join(*pThread, 0);
+ MP_ASSERT(r == 0);
+}
+#elif defined(_WIN32)
+typedef HANDLE MicroProfileThread;
+DWORD __stdcall ThreadTrampoline(void* pFunc)
+{
+ MicroProfileThreadFunc F = (MicroProfileThreadFunc)pFunc;
+ return (uint32_t)(uintptr_t)F(0);
+}
+
+void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
+{
+ *pThread = CreateThread(0, 0, ThreadTrampoline, Func, 0, 0);
+}
+void MicroProfileThreadJoin(MicroProfileThread* pThread)
+{
+ WaitForSingleObject(*pThread, INFINITE);
+ CloseHandle(*pThread);
+}
+#else
+#include
+typedef std::thread* MicroProfileThread;
+inline void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
+{
+ *pThread = MP_ALLOC_OBJECT(std::thread);
+ new(*pThread) std::thread(Func, nullptr);
+}
+inline void MicroProfileThreadJoin(MicroProfileThread* pThread)
+{
+ (*pThread)->join();
+ (*pThread)->~thread();
+ MP_FREE(*pThread);
+ *pThread = 0;
+}
+#endif
+#endif
+
+#if MICROPROFILE_WEBSERVER
+
+#ifdef _WIN32
+#define MP_INVALID_SOCKET(f) (f == INVALID_SOCKET)
+#else
+#include
+#include
+#include
+#define MP_INVALID_SOCKET(f) (f < 0)
+#endif
+
+void MicroProfileWebServerStart();
+void MicroProfileWebServerStop();
+void MicroProfileWebServerJoin();
+bool MicroProfileWebServerUpdate();
+void MicroProfileDumpToFile();
+
+#else
+
+#define MicroProfileWebServerStart() \
+ do \
+ { \
+ } while(0)
+#define MicroProfileWebServerStop() \
+ do \
+ { \
+ } while(0)
+#define MicroProfileWebServerJoin() \
+ do \
+ { \
+ } while(0)
+#define MicroProfileWebServerUpdate() false
+#define MicroProfileDumpToFile() \
+ do \
+ { \
+ } while(0)
+#endif
+
+#include
+#include
+#include
+#include
+
+#if MICROPROFILE_DEBUG
+#ifdef _WIN32
+void uprintf(const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buffer[1024];
+ stbsp_vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
+ OutputDebugStringA(buffer);
+ va_end(args);
+}
+#else
+#define uprintf(...) printf(__VA_ARGS__)
+#endif
+#else
+#define uprintf(...) \
+ do \
+ { \
+ sizeof(__VA_ARGS__); \
+ } while(0)
+#endif
+
+#define S g_MicroProfile
+
+MicroProfile g_MicroProfile;
+#ifdef MICROPROFILE_IOS
+// iOS doesn't support __thread
+static pthread_key_t g_MicroProfileThreadLogKey;
+static pthread_once_t g_MicroProfileThreadLogKeyOnce = PTHREAD_ONCE_INIT;
+
+static void MicroProfileCreateThreadLogKey()
+{
+ pthread_key_create(&g_MicroProfileThreadLogKey, NULL);
+}
+#else
+MP_THREAD_LOCAL MicroProfileThreadLog* g_MicroProfileThreadLogThreadLocal = 0;
+#endif
+static bool g_bUseLock = false; /// This is used because windows does not support using mutexes under dll init(which is where global initialization is handled)
+
+MICROPROFILE_DEFINE(g_MicroProfileFlip, "MicroProfile", "MicroProfileFlip", MP_GREEN4);
+MICROPROFILE_DEFINE(g_MicroProfileThreadLoop, "MicroProfile", "ThreadLoop", MP_GREEN4);
+MICROPROFILE_DEFINE(g_MicroProfileClear, "MicroProfile", "Clear", MP_GREEN4);
+MICROPROFILE_DEFINE(g_MicroProfileAccumulate, "MicroProfile", "Accumulate", MP_GREEN4);
+MICROPROFILE_DEFINE(g_MicroProfileContextSwitchSearch, "MicroProfile", "ContextSwitchSearch", MP_GREEN4);
+MICROPROFILE_DEFINE(g_MicroProfileGpuSubmit, "MicroProfile", "MicroProfileGpuSubmit", MP_HOTPINK2);
+MICROPROFILE_DEFINE(g_MicroProfileSendLoop, "MicroProfile", "MicroProfileSocketSendLoop", MP_GREEN4);
+MICROPROFILE_DEFINE_LOCAL_ATOMIC_COUNTER(g_MicroProfileBytesPerFlip, "microprofile/bytesperflip");
+
+// void MicroProfileHashTableInit(MicroProfileHashTable* pTable, uint32_t nInitialSize, MicroProfileHashCompareFunction CompareFunc, MicroProfileHashFunction HashFunc);
+void MicroProfileHashTableDestroy(MicroProfileHashTable* pTable);
+uint64_t MicroProfileHashTableHash(MicroProfileHashTable* pTable, uint64_t K);
+void MicroProfileHashTableGrow(MicroProfileHashTable* pTable);
+
+bool MicroProfileHashTableSet(MicroProfileHashTable* pTable, uint64_t Key, uintptr_t Value, uint64_t H, bool bAllowGrow);
+bool MicroProfileHashTableGet(MicroProfileHashTable* pTable, uint64_t Key, uintptr_t* pValue);
+bool MicroProfileHashTableRemove(MicroProfileHashTable* pTable, uint64_t Key);
+
+bool MicroProfileHashTableSetString(MicroProfileHashTable* pTable, const char* pKey, const char* pValue);
+bool MicroProfileHashTableGetString(MicroProfileHashTable* pTable, const char* pKey, const char** pValue);
+bool MicroProfileHashTableRemoveString(MicroProfileHashTable* pTable, const char* pKey);
+
+bool MicroProfileHashTableSetPtr(MicroProfileHashTable* pTable, const void* pKey, void* pValue);
+template
+bool MicroProfileHashTableGetPtr(MicroProfileHashTable* pTable, const void* pKey, T** pValue = nullptr);
+bool MicroProfileHashTableRemovePtr(MicroProfileHashTable* pTable, const void* pKey);
+
+enum
+{
+ ESTRINGINTERN_LOWERCASE = 1,
+ ESTRINGINTERN_FORCEFORWARDSLASH = 0x2,
+};
+const char* MicroProfileStringIntern(const char* pStr);
+const char* MicroProfileStringInternLower(const char* pStr);
+const char* MicroProfileStringInternSlash(const char* pStr);
+const char* MicroProfileStringIntern(const char* pStr, uint32_t nLen, uint32_t nInternalFlags = 0);
+
+void MicroProfileStringsInit(MicroProfileStrings* pStrings);
+void MicroProfileStringsDestroy(MicroProfileStrings* pStrings);
+
+MicroProfileToken MicroProfileCounterTokenInit(int nParent, uint32_t nFlags);
+void MicroProfileCounterTokenInitName(MicroProfileToken nToken, const char* pName);
+void MicroProfileCounterConfigToken(MicroProfileToken, uint32_t eFormat, int64_t nLimit, uint32_t nFlags);
+uint16_t MicroProfileFindGroup(const char* pGroup);
+
+inline std::recursive_mutex& MicroProfileMutex()
+{
+ static std::recursive_mutex Mutex;
+ return Mutex;
+}
+std::recursive_mutex& MicroProfileGetMutex()
+{
+ return MicroProfileMutex();
+}
+
+inline std::recursive_mutex& MicroProfileTimelineMutex()
+{
+ static std::recursive_mutex Mutex;
+ return Mutex;
+}
+MICROPROFILE_API MicroProfile* MicroProfileGet()
+{
+ return &g_MicroProfile;
+}
+
+MicroProfileThreadLog* MicroProfileCreateThreadLog(const char* pName);
+MicroProfileThreadLogGpu* MicroProfileThreadLogGpuAllocInternal();
+void* MicroProfileSocketSenderThread(void*);
+
+void MicroProfileInit()
+{
+ static bool bOnce = true;
+ if(!bOnce)
+ {
+ return;
+ }
+
+ std::recursive_mutex& mutex = MicroProfileMutex();
+ bool bUseLock = g_bUseLock;
+ if(bUseLock)
+ mutex.lock();
+ if(bOnce)
+ {
+ bOnce = false;
+ memset(&S, 0, sizeof(S));
+
+ MicroProfileStringsInit(&S.Strings);
+
+ // these strings are used for counter names inside the string
+ S.CounterToken_MicroProfile = MicroProfileCounterTokenInit(-1, 0);
+ S.CounterToken_StringBlock = MicroProfileCounterTokenInit(S.CounterToken_MicroProfile, 0);
+ S.CounterToken_StringBlock_Count = MicroProfileCounterTokenInit(S.CounterToken_StringBlock, 0);
+ S.CounterToken_StringBlock_Waste = MicroProfileCounterTokenInit(S.CounterToken_StringBlock, 0);
+ S.CounterToken_StringBlock_Strings = MicroProfileCounterTokenInit(S.CounterToken_StringBlock, 0);
+ S.CounterToken_StringBlock_Memory = MicroProfileCounterTokenInit(S.CounterToken_StringBlock, 0);
+
+ S.CounterToken_Alloc = MicroProfileCounterTokenInit(S.CounterToken_MicroProfile, 0);
+ S.CounterToken_Alloc_Memory = MicroProfileCounterTokenInit(S.CounterToken_Alloc, 0);
+ S.CounterToken_Alloc_Count = MicroProfileCounterTokenInit(S.CounterToken_Alloc, 0);
+
+ MicroProfileCounterTokenInitName(S.CounterToken_MicroProfile, "microprofile");
+ MicroProfileCounterTokenInitName(S.CounterToken_StringBlock, "stringblock");
+ MicroProfileCounterTokenInitName(S.CounterToken_StringBlock_Count, "count");
+ MicroProfileCounterTokenInitName(S.CounterToken_StringBlock_Waste, "waste");
+ MicroProfileCounterTokenInitName(S.CounterToken_StringBlock_Strings, "strings");
+ MicroProfileCounterTokenInitName(S.CounterToken_StringBlock_Memory, "memory");
+
+ MicroProfileCounterTokenInitName(S.CounterToken_Alloc, "alloc");
+ MicroProfileCounterTokenInitName(S.CounterToken_Alloc_Memory, "memory");
+ MicroProfileCounterTokenInitName(S.CounterToken_Alloc_Count, "count");
+
+ S.nMemUsage += sizeof(S);
+ for(int i = 0; i < MICROPROFILE_MAX_GROUPS; ++i)
+ {
+ S.GroupInfo[i].pName[0] = '\0';
+ }
+ for(int i = 0; i < MICROPROFILE_MAX_CATEGORIES; ++i)
+ {
+ S.CategoryInfo[i].pName[0] = '\0';
+ memset(S.CategoryInfo[i].nGroupMask, 0, sizeof(S.CategoryInfo[i].nGroupMask));
+ }
+ memcpy(&S.CategoryInfo[0].pName[0], "default", sizeof("default"));
+ S.nCategoryCount = 1;
+ for(int i = 0; i < MICROPROFILE_MAX_TIMERS; ++i)
+ {
+ S.TimerInfo[i].pName[0] = '\0';
+ }
+ S.nGroupCount = 0;
+ S.nFlipStartTick = MP_TICK();
+ S.nContextSwitchStalledTick = MP_TICK();
+ S.nAggregateFlipTick = MP_TICK();
+ memset(S.nActiveGroups, 0, sizeof(S.nActiveGroups));
+ S.nFrozen = 0;
+ S.nWasFrozen = 0;
+ memset(S.nForceGroups, 0, sizeof(S.nForceGroups));
+ memset(S.nActiveGroupsWanted, 0, sizeof(S.nActiveGroupsWanted));
+ S.nStartEnabled = 0;
+ S.nAllThreadsWanted = 1;
+ S.nAggregateFlip = 0;
+ S.nTotalTimers = 0;
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i)
+ {
+ S.Graph[i].nToken = MICROPROFILE_INVALID_TOKEN;
+ }
+ S.fReferenceTime = 33.33f;
+ S.fRcpReferenceTime = 1.f / S.fReferenceTime;
+ S.nFreeListHead = -1;
+ int64_t nTick = MP_TICK();
+ for(int i = 0; i < MICROPROFILE_MAX_FRAME_HISTORY; ++i)
+ {
+ S.Frames[i].nFrameStartCpu = nTick;
+ S.Frames[i].nFrameStartGpu = MICROPROFILE_INVALID_TICK;
+ }
+ S.nWebServerPort = MICROPROFILE_WEBSERVER_PORT; // Use defined value as default port
+ S.nWebServerDataSent = (uint64_t)-1;
+ S.WebSocketTimers = -1;
+ S.WebSocketCounters = -1;
+ S.WebSocketGroups = -1;
+ S.nSocketFail = 0;
+
+ S.DumpFrameCount = MICROPROFILE_WEBSERVER_DEFAULT_FRAMES;
+
+#if MICROPROFILE_COUNTER_HISTORY
+ S.nCounterHistoryPut = 0;
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_COUNTERS; ++i)
+ {
+ S.nCounterMin[i] = 0x7fffffffffffffff;
+ S.nCounterMax[i] = 0x8000000000000000;
+ }
+#endif
+ S.GpuQueue = MICROPROFILE_GPU_INIT_QUEUE("GPU");
+ S.pGpuGlobal = MicroProfileThreadLogGpuAllocInternal();
+ MicroProfileGpuBegin(0, S.pGpuGlobal);
+
+ S.pJsonSettings = 0;
+ S.pJsonSettingsName = nullptr;
+ S.nJsonSettingsPending = 0;
+ S.nJsonSettingsBufferSize = 0;
+ S.nWSWasConnected = 0;
+
+ for(uint32_t i = 0; i < MICROPROFILE_TIMELINE_MAX_TOKENS; ++i)
+ {
+ S.TimelineTokenFrameEnter[i] = MICROPROFILE_INVALID_FRAME;
+ S.TimelineTokenFrameLeave[i] = MICROPROFILE_INVALID_FRAME;
+ S.TimelineTokenStaticString[i] = nullptr;
+ S.TimelineToken[i] = 0;
+ }
+ memset(&S.AccumMinTimers[0], 0xFF, sizeof(S.AccumMinTimers));
+ S.CountersDouble = (std::atomic*)&S.Counters;
+#if MICROPROFILE_COUNTER_HISTORY
+ S.dCounterHistory = (double*)S.nCounterHistory;
+ S.dCounterMax = (double*)S.nCounterMax;
+ S.dCounterMin = (double*)S.nCounterMin;
+#endif
+ }
+ MicroProfileUpdateSettingsPath();
+
+#if MICROPROFILE_FRAME_EXTRA_DATA
+ S.FrameExtraCounterData = (MicroProfileFrameExtraCounterData*)1;
+#endif
+ MicroProfileCounterConfigToken(S.CounterToken_Alloc_Memory, MICROPROFILE_COUNTER_FORMAT_BYTES, 0, MICROPROFILE_COUNTER_FLAG_DETAILED);
+ MICROPROFILE_COUNTER_CONFIG("MicroProfile/ThreadLog/Memory", MICROPROFILE_COUNTER_FORMAT_BYTES, 0, MICROPROFILE_COUNTER_FLAG_DETAILED);
+
+ if(bUseLock)
+ {
+ mutex.unlock();
+ }
+}
+void MicroProfileUpdateSettingsPath()
+{
+ if(S.pSettings)
+ {
+ MicroProfileFreeInternal((void*)S.pSettings);
+ S.pSettings = nullptr;
+ }
+ if(S.pSettingsReadOnly)
+ {
+ MicroProfileFreeInternal((void*)S.pSettingsReadOnly);
+ S.pSettingsReadOnly = nullptr;
+ }
+ if(S.pSettingsTemp)
+ {
+ MicroProfileFreeInternal((void*)S.pSettingsTemp);
+ S.pSettingsTemp = nullptr;
+ }
+ auto DupeString = [](const char* BasePath, const char* File) -> const char*
+ {
+ size_t BaseLen = strlen(BasePath);
+ bool TrailingSlash = BaseLen > 1 && (BasePath[BaseLen - 1] == '\\' || BasePath[BaseLen - 1] == '/');
+ size_t Len = BaseLen + strlen(File) + 2;
+ char* Data = (char*)MicroProfileAllocInternal(Len + 1, 1);
+#ifdef _WIN32
+ char Slash = '\\';
+#else
+ char Slash = '/';
+#endif
+ if(TrailingSlash)
+ snprintf(Data, Len, "%s%s", BasePath, File);
+ else
+ snprintf(Data, Len, "%s%c%s", BasePath, Slash, File);
+
+ return Data;
+ };
+ const char* pBaseSettingsPath = MICROPROFILE_GET_SETTINGS_FILE_PATH;
+ S.pSettings = DupeString(pBaseSettingsPath, MICROPROFILE_SETTINGS_FILE);
+ S.pSettingsReadOnly = DupeString(pBaseSettingsPath, MICROPROFILE_SETTINGS_FILE_BUILTIN);
+ S.pSettingsTemp = DupeString(pBaseSettingsPath, MICROPROFILE_SETTINGS_FILE MICROPROFILE_SETTINGS_FILE_TEMP);
+}
+
+void MicroProfileJoinContextSwitchTrace();
+
+void MicroProfileShutdown()
+{
+ {
+ std::lock_guard Lock(MicroProfileMutex());
+ S.nMicroProfileShutdown = 1;
+ MicroProfileStopContextSwitchTrace();
+ }
+ MicroProfileWebServerJoin();
+ MicroProfileJoinContextSwitchTrace();
+ {
+
+ std::lock_guard Lock(MicroProfileMutex());
+ if(S.pJsonSettings)
+ {
+ MP_FREE(S.pJsonSettings);
+ S.pJsonSettings = 0;
+ S.pJsonSettingsName = 0;
+ S.nJsonSettingsBufferSize = 0;
+ }
+ if(S.pGPU)
+ {
+ MicroProfileGpuShutdownPlatform();
+ }
+ MicroProfileHashTableDestroy(&S.Strings.HashTable);
+ MicroProfileStringsDestroy(&S.Strings);
+ MICROPROFILE_FREE_NON_ALIGNED(S.WSBuf.pBufferAllocation);
+
+ MicroProfileFreeGpuQueue(S.GpuQueue);
+ MicroProfileThreadLogGpuFree(S.pGpuGlobal);
+
+ for(uint32_t i = 0; i < S.nNumLogs; ++i)
+ {
+#if MICROPROFILE_ASSERT_LOG_FREED
+ MP_ASSERT(S.Pool[i]->nActive != 1);
+#endif
+ MP_FREE(S.Pool[i]);
+ }
+
+ for(uint32_t i = 0; i < S.nNumLogsGpu; ++i)
+ {
+#if MICROPROFILE_ASSERT_LOG_FREED
+ MP_ASSERT(!S.PoolGpu[i]->nAllocated);
+#endif
+ MP_FREE(S.PoolGpu[i]);
+ }
+ MicroProfileFreeInternal((void*)S.pSettings);
+ S.pSettings = nullptr;
+ MicroProfileFreeInternal((void*)S.pSettingsReadOnly);
+ S.pSettingsReadOnly = nullptr;
+ MicroProfileFreeInternal((void*)S.pSettingsTemp);
+ S.pSettingsTemp = nullptr;
+ }
+}
+
+static void* MicroProfileAutoFlipThread(void*)
+{
+ MicroProfileOnThreadCreate("AutoFlipThread");
+ while(0 == S.nAutoFlipStop.load())
+ {
+ MICROPROFILE_SCOPEI("MICROPROFILE", "AutoFlipThread", 0);
+ MicroProfileSleep(S.nAutoFlipDelay);
+ MicroProfileFlip(0);
+ }
+ MicroProfileOnThreadExit();
+ return 0;
+}
+
+void MicroProfileStartAutoFlip(uint32_t nMsDelay)
+{
+ S.nAutoFlipDelay = nMsDelay;
+ S.nAutoFlipStop.store(0);
+ MicroProfileThreadStart(&S.AutoFlipThread, MicroProfileAutoFlipThread);
+}
+void MicroProfileStopAutoFlip()
+{
+ S.nAutoFlipStop.store(1);
+ MicroProfileThreadJoin(&S.AutoFlipThread);
+}
+
+void MicroProfileEnableFrameExtraCounterData()
+{
+ // should not be called at the same time as MicroProfileFlip.
+ if(!S.FrameExtraCounterData)
+ {
+ S.FrameExtraCounterData = (MicroProfileFrameExtraCounterData*)1;
+ }
+}
+
+void MicroProfileCsvConfigEnd()
+{
+ MP_ASSERT(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG);
+ S.CsvConfig.State = MicroProfileCsvConfig::ACTIVE;
+}
+void MicroProfileCsvConfigBegin(uint32_t MaxTimers, uint32_t MaxGroups, uint32_t MaxCounters, uint32_t Flags)
+{
+ MP_ASSERT(S.CsvConfig.State == MicroProfileCsvConfig::INACTIVE); // right now, only support being configured once.
+ uint32_t TotalElements = MaxTimers + MaxGroups + MaxCounters;
+ uint32_t BaseSize = (sizeof(MicroProfileCsvConfig) + 7) & 7;
+ uint32_t TimerIndexSize = sizeof(uint16_t) * MaxTimers;
+ uint32_t GroupIndexSize = sizeof(uint16_t) * MaxGroups;
+ uint32_t CounterIndexSize = sizeof(uint16_t) * MaxCounters;
+ uint32_t FrameBlockSize = TotalElements * sizeof(uint64_t);
+ uint32_t FrameDataSize = FrameBlockSize * MICROPROFILE_MAX_FRAME_HISTORY;
+ S.CsvConfig.NumTimers = 0;
+ S.CsvConfig.NumGroups = 0;
+ S.CsvConfig.NumCounters = 0;
+ S.CsvConfig.MaxTimers = MaxTimers;
+ S.CsvConfig.MaxGroups = MaxGroups;
+ S.CsvConfig.MaxCounters = MaxCounters;
+ S.CsvConfig.TotalElements = TotalElements;
+ S.CsvConfig.TimerIndices = (uint16_t*)MicroProfileAllocInternal(TimerIndexSize, alignof(uint16_t));
+ S.CsvConfig.pTimerNames = (const char**)MicroProfileAllocInternal(MaxTimers * sizeof(const char*), alignof(const char*));
+ memset(S.CsvConfig.pTimerNames, 0, MaxTimers * sizeof(const char*));
+ for(uint32_t i = 0; i < MaxTimers; ++i)
+ S.CsvConfig.TimerIndices[i] = UINT16_MAX;
+ S.CsvConfig.pGroupNames = (const char**)MicroProfileAllocInternal(MaxGroups * sizeof(const char*), alignof(const char*));
+ memset(S.CsvConfig.pGroupNames, 0, MaxGroups * sizeof(const char*));
+ S.CsvConfig.GroupIndices = (uint16_t*)MicroProfileAllocInternal(GroupIndexSize, alignof(uint16_t));
+ for(uint32_t i = 0; i < MaxGroups; ++i)
+ S.CsvConfig.GroupIndices[i] = UINT16_MAX;
+ S.CsvConfig.pCounterNames = (const char**)MicroProfileAllocInternal(MaxCounters * sizeof(const char*), alignof(const char*));
+ memset(S.CsvConfig.pCounterNames, 0, MaxCounters * sizeof(const char*));
+ S.CsvConfig.CounterIndices = (uint16_t*)MicroProfileAllocInternal(CounterIndexSize, alignof(uint16_t));
+ for(uint32_t i = 0; i < MaxCounters; ++i)
+ S.CsvConfig.CounterIndices[i] = UINT16_MAX;
+ S.CsvConfig.FrameData = (uint64_t*)MicroProfileAllocInternal(FrameDataSize, alignof(uint64_t));
+ memset(S.CsvConfig.FrameData, 0, FrameDataSize);
+ S.CsvConfig.State = MicroProfileCsvConfig::CONFIG;
+ S.CsvConfig.Flags = Flags;
+}
+void MicroProfileCsvConfigAddTimer(const char* Group, const char* Timer, const char* Name, MicroProfileTokenType Type)
+{
+ MP_ASSERT(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG);
+ if(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG && S.CsvConfig.NumTimers < S.CsvConfig.MaxTimers)
+ {
+ MicroProfileToken ret = MicroProfileGetToken(Group, Timer, MP_AUTO, Type, MICROPROFILE_TIMER_FLAG_PLACEHOLDER);
+ if(ret != MICROPROFILE_INVALID_TOKEN)
+ {
+ MP_ASSERT(S.CsvConfig.NumTimers < S.CsvConfig.MaxTimers);
+ uint16_t TimerIndex = MicroProfileGetTimerIndex(ret);
+ for(uint32_t i = 0; i < S.CsvConfig.NumTimers; ++i)
+ {
+ if(S.CsvConfig.TimerIndices[i] == TimerIndex)
+ return;
+ }
+ S.CsvConfig.pTimerNames[S.CsvConfig.NumTimers] = Name;
+ S.CsvConfig.TimerIndices[S.CsvConfig.NumTimers++] = TimerIndex;
+ }
+ }
+}
+void MicroProfileCsvConfigAddGroup(const char* Group, const char* Name)
+{
+ MP_ASSERT(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG);
+ if(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG && S.CsvConfig.NumGroups < S.CsvConfig.MaxGroups)
+ {
+ uint16_t Index = MicroProfileFindGroup(Group);
+ MP_ASSERT(UINT16_MAX != Index);
+ if(UINT16_MAX != Index)
+ {
+ MP_ASSERT(S.CsvConfig.NumGroups < S.CsvConfig.MaxGroups);
+ for(uint32_t i = 0; i < S.CsvConfig.NumGroups; ++i)
+ {
+ if(S.CsvConfig.GroupIndices[i] == Index)
+ return;
+ }
+ S.CsvConfig.pGroupNames[S.CsvConfig.NumGroups] = Name;
+ S.CsvConfig.GroupIndices[S.CsvConfig.NumGroups++] = Index;
+ }
+ }
+}
+void MicroProfileCsvConfigAddCounter(const char* CounterName, const char* Name)
+{
+ MP_ASSERT(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG);
+ if(S.CsvConfig.State == MicroProfileCsvConfig::CONFIG && S.CsvConfig.NumCounters < S.CsvConfig.MaxCounters)
+ {
+ MicroProfileToken Token = MicroProfileGetCounterToken(CounterName, 0);
+ if(MICROPROFILE_INVALID_TOKEN != Token)
+ {
+ MP_ASSERT(Token < UINT16_MAX);
+ MP_ASSERT(S.CsvConfig.NumCounters < S.CsvConfig.MaxCounters);
+ for(uint32_t i = 0; i < S.CsvConfig.NumCounters; ++i)
+ {
+ if(S.CsvConfig.CounterIndices[i] == (uint16_t)Token)
+ return;
+ }
+ S.CsvConfig.pCounterNames[S.CsvConfig.NumCounters] = Name;
+ S.CsvConfig.CounterIndices[S.CsvConfig.NumCounters++] = (uint16_t)Token;
+ }
+ }
+}
+
+#ifdef MICROPROFILE_IOS
+inline MicroProfileThreadLog* MicroProfileGetThreadLog()
+{
+ pthread_once(&g_MicroProfileThreadLogKeyOnce, MicroProfileCreateThreadLogKey);
+ return (MicroProfileThreadLog*)pthread_getspecific(g_MicroProfileThreadLogKey);
+}
+
+inline void MicroProfileSetThreadLog(MicroProfileThreadLog* pLog)
+{
+ pthread_once(&g_MicroProfileThreadLogKeyOnce, MicroProfileCreateThreadLogKey);
+ pthread_setspecific(g_MicroProfileThreadLogKey, pLog);
+}
+#else
+MicroProfileThreadLog* MicroProfileGetThreadLog()
+{
+ return g_MicroProfileThreadLogThreadLocal;
+}
+void MicroProfileSetThreadLog(MicroProfileThreadLog* pLog)
+{
+ g_MicroProfileThreadLogThreadLocal = pLog;
+}
+#endif
+
+MicroProfileThreadLog* MicroProfileGetThreadLog2()
+{
+ MicroProfileThreadLog* pLog = MicroProfileGetThreadLog();
+ if(!pLog)
+ {
+ MicroProfileInitThreadLog();
+ pLog = MicroProfileGetThreadLog();
+ }
+ return pLog;
+}
+
+struct MicroProfileScopeLock
+{
+ bool bUseLock;
+ int nUnlock;
+ std::recursive_mutex& m;
+ MicroProfileScopeLock(std::recursive_mutex& m)
+ : bUseLock(g_bUseLock)
+ , nUnlock(0)
+ , m(m)
+ {
+ if(bUseLock)
+ m.lock();
+ }
+ ~MicroProfileScopeLock()
+ {
+ MP_ASSERT(nUnlock == 0);
+ if(bUseLock)
+ m.unlock();
+ }
+ void Unlock()
+ {
+ MP_ASSERT(bUseLock);
+ m.unlock();
+ nUnlock++;
+ }
+ void Lock()
+ {
+ m.lock();
+ nUnlock--;
+ }
+};
+
+void MicroProfileLogReset(MicroProfileThreadLog* pLog);
+void MicroProfileLogClearInternal(MicroProfileThreadLog* pLog);
+
+MicroProfileThreadLog* MicroProfileCreateThreadLog(const char* pName)
+{
+ MicroProfileScopeLock L(MicroProfileMutex());
+
+ if(S.nNumLogs == MICROPROFILE_MAX_THREADS && S.nFreeListHead == -1)
+ {
+ uprintf("recycling thread logs\n");
+ // reuse the oldest.
+ MicroProfileThreadLog* pOldest = 0;
+ uint32_t nIdleFrames = 0;
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i)
+ {
+ MicroProfileThreadLog* pLog = S.Pool[i];
+ uprintf("tlactive %p, %d. idle:%d\n", pLog, pLog->nActive, pLog->nIdleFrames);
+ if(pLog->nActive == 2)
+ {
+ if(pLog->nIdleFrames >= nIdleFrames)
+ {
+ nIdleFrames = pLog->nIdleFrames;
+ pOldest = pLog;
+ }
+ }
+ }
+ MP_ASSERT(pOldest);
+ MicroProfileLogReset(pOldest);
+ }
+
+ MicroProfileThreadLog* pLog = 0;
+ if(S.nFreeListHead != -1)
+ {
+ pLog = S.Pool[S.nFreeListHead];
+ MP_ASSERT(pLog->nPut.load() == 0);
+ MP_ASSERT(pLog->nGet.load() == 0);
+ S.nFreeListHead = S.Pool[S.nFreeListHead]->nFreeListNext;
+ }
+ else
+ {
+ MICROPROFILE_COUNTER_ADD("MicroProfile/ThreadLog/Allocated", 1);
+ MICROPROFILE_COUNTER_ADD("MicroProfile/ThreadLog/Memory", sizeof(MicroProfileThreadLog));
+ pLog = MP_ALLOC_OBJECT(MicroProfileThreadLog);
+ MicroProfileLogClearInternal(pLog);
+ S.nMemUsage += sizeof(MicroProfileThreadLog);
+ pLog->nLogIndex = S.nNumLogs;
+ MP_ASSERT(S.nNumLogs < MICROPROFILE_MAX_THREADS);
+ S.Pool[S.nNumLogs++] = pLog;
+ }
+ int len = 0;
+ if(pName)
+ {
+ len = (int)strlen(pName);
+ int maxlen = sizeof(pLog->ThreadName) - 1;
+ len = len < maxlen ? len : maxlen;
+ memcpy(&pLog->ThreadName[0], pName, len);
+ }
+ else
+ {
+ len = snprintf(&pLog->ThreadName[0], sizeof(pLog->ThreadName) - 1, "TID:[%" PRId64 "]", (int64_t)MP_GETCURRENTTHREADID());
+ }
+ pLog->ThreadName[len] = '\0';
+ pLog->nThreadId = MP_GETCURRENTTHREADID();
+ pLog->nFreeListNext = -1;
+ pLog->nActive = 1;
+ return pLog;
+}
+
+void MicroProfileOnThreadCreate(const char* pThreadName)
+{
+ char Buffer[64];
+ g_bUseLock = true;
+ MicroProfileInit();
+ MP_ASSERT(MicroProfileGetThreadLog() == 0);
+ MicroProfileThreadLog* pLog = MicroProfileCreateThreadLog(pThreadName ? pThreadName : MicroProfileGetThreadName(Buffer));
+ (void)Buffer;
+ MP_ASSERT(pLog);
+ MicroProfileSetThreadLog(pLog);
+}
+
+void MicroProfileThreadLogGpuReset(MicroProfileThreadLogGpu* pLog)
+{
+ MP_ASSERT(pLog->nAllocated);
+ pLog->pContext = (void*)-1;
+ pLog->nStart = (uint32_t)-1;
+ pLog->nPut = 0;
+ pLog->nStackScope = 0;
+}
+
+MicroProfileThreadLogGpu* MicroProfileThreadLogGpuAllocInternal()
+{
+ MicroProfileThreadLogGpu* pLog = 0;
+ for(uint32_t i = 0; i < S.nNumLogsGpu; ++i)
+ {
+ MicroProfileThreadLogGpu* pNextLog = S.PoolGpu[i];
+ if(pNextLog && !pNextLog->nAllocated)
+ {
+ pLog = pNextLog;
+ break;
+ }
+ }
+ if(!pLog)
+ {
+ pLog = MP_ALLOC_OBJECT(MicroProfileThreadLogGpu);
+ int nLogIndex = S.nNumLogsGpu++;
+ MP_ASSERT(nLogIndex < MICROPROFILE_MAX_THREADS);
+ pLog->nId = nLogIndex;
+ S.PoolGpu[nLogIndex] = pLog;
+ }
+ pLog->nAllocated = 1;
+ MicroProfileThreadLogGpuReset(pLog);
+ return pLog;
+}
+
+MicroProfileThreadLogGpu* MicroProfileThreadLogGpuAlloc()
+{
+ std::lock_guard Lock(MicroProfileMutex());
+ return MicroProfileThreadLogGpuAllocInternal();
+}
+
+void MicroProfileThreadLogGpuFree(MicroProfileThreadLogGpu* pLog)
+{
+ MP_ASSERT(pLog->nAllocated);
+ pLog->nAllocated = 0;
+}
+
+int MicroProfileGetGpuQueue(const char* pQueueName)
+{
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; i++)
+ {
+ MicroProfileThreadLog* pLog = S.Pool[i];
+ if(pLog && pLog->nGpu && pLog->nActive && 0 == MP_STRCASECMP(pQueueName, pLog->ThreadName))
+ {
+ return i;
+ }
+ }
+ MP_ASSERT(0); // call MicroProfileInitGpuQueue
+ return 0;
+}
+
+MicroProfileThreadLog* MicroProfileGetGpuQueueLog(const char* pQueueName)
+{
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; i++)
+ {
+ MicroProfileThreadLog* pLog = S.Pool[i];
+ if(pLog && pLog->nGpu && pLog->nActive && 0 == MP_STRCASECMP(pQueueName, pLog->ThreadName))
+ {
+ return pLog;
+ }
+ }
+ MP_ASSERT(0); // call MicroProfileInitGpuQueue
+ return 0;
+}
+
+int MicroProfileInitGpuQueue(const char* pQueueName)
+{
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i)
+ {
+ MicroProfileThreadLog* pLog = S.Pool[i];
+ if(pLog && 0 == MP_STRCASECMP(pQueueName, pLog->ThreadName))
+ {
+
+ MP_ASSERT(0); // call MicroProfileInitGpuQueue only once per CommandQueue. name must not clash with threadname
+ }
+ }
+ MicroProfileThreadLog* pLog = MicroProfileCreateThreadLog(pQueueName);
+ pLog->nGpu = 1;
+ pLog->nThreadId = 0;
+ for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i)
+ {
+ if(S.Pool[i] == pLog)
+ {
+ return i;
+ }
+ }
+ MP_BREAK();
+ return 0;
+}
+
+void MicroProfileFreeGpuQueue(int nQueue)
+{
+ MicroProfileThreadLog* pLog = S.Pool[nQueue];
+ if(pLog)
+ {
+ MP_ASSERT(pLog->nActive == 1);
+ pLog->nActive = 2;
+ }
+}
+
+MicroProfileThreadLogGpu* MicroProfileGetGlobalGpuThreadLog()
+{
+ return S.pGpuGlobal;
+}
+
+MICROPROFILE_API int MicroProfileGetGlobalGpuQueue()
+{
+ return S.GpuQueue;
+}
+void MicroProfileLogClearInternal(MicroProfileThreadLog* pLog)
+{
+ // can't clear atomics..
+ void* pStart = (void*)&pLog->Log[0];
+ void* pEnd = (void*)(pLog + 1);
+ memset(pStart, 0, (uintptr_t)pEnd - (uintptr_t)pStart);
+ pLog->nPut.store(0);
+ pLog->nGet.store(0);
+}
+void MicroProfileLogReset(MicroProfileThreadLog* pLog)
+{
+ std::lock_guard Lock(MicroProfileMutex());
+
+ int32_t nLogIndex = -1;
+ for(int i = 0; i < MICROPROFILE_MAX_THREADS; ++i)
+ {
+ if(pLog == S.Pool[i])
+ {
+ nLogIndex = i;
+ break;
+ }
+ }
+ MP_ASSERT(nLogIndex < MICROPROFILE_MAX_THREADS && nLogIndex > 0);
+ MicroProfileLogClearInternal(pLog);
+ pLog->nFreeListNext = S.nFreeListHead;
+ S.nFreeListHead = nLogIndex;
+ for(int i = 0; i < MICROPROFILE_MAX_FRAME_HISTORY; ++i)
+ {
+ S.Frames[i].nLogStart[nLogIndex] = 0;
+ }
+}
+
+void MicroProfileOnThreadExit()
+{
+ MicroProfileThreadLog* pLog = MicroProfileGetThreadLog();
+ if(pLog)
+ {
+ MP_ASSERT(pLog->nActive == 1);
+ pLog->nActive = 2;
+ }
+}
+
+void MicroProfileInitThreadLog()
+{
+ MicroProfileOnThreadCreate(nullptr);
+}
+
+MicroProfileToken MicroProfileFindTokenInternal(const char* pGroup, const char* pName)
+{
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ for(uint32_t i = 0; i < S.nTotalTimers; ++i)
+ {
+ if(!MP_STRCASECMP(pName, S.TimerInfo[i].pName) && !MP_STRCASECMP(pGroup, S.GroupInfo[S.TimerToGroup[i]].pName))
+ {
+ return S.TimerInfo[i].nToken;
+ }
+ }
+ return MICROPROFILE_INVALID_TOKEN;
+}
+MicroProfileToken MicroProfileFindToken(const char* pGroup, const char* pName)
+{
+ return MicroProfileGetToken(pGroup, pName, MP_AUTO, MicroProfileTokenTypeCpu, MICROPROFILE_TIMER_FLAG_PLACEHOLDER);
+}
+
+uint16_t MicroProfileFindGroup(const char* pGroup)
+{
+ for(uint32_t i = 0; i < S.nGroupCount; ++i)
+ {
+ if(!MP_STRCASECMP(pGroup, S.GroupInfo[i].pName))
+ {
+ return i;
+ }
+ }
+ return UINT16_MAX;
+}
+
+uint16_t MicroProfileGetGroup(const char* pGroup, MicroProfileTokenType Type)
+{
+ for(uint32_t i = 0; i < S.nGroupCount; ++i)
+ {
+ if(!MP_STRCASECMP(pGroup, S.GroupInfo[i].pName))
+ {
+ return i;
+ }
+ }
+ uint16_t nGroupIndex = 0xffff;
+ uint32_t nLen = (uint32_t)strlen(pGroup);
+ if(nLen > MICROPROFILE_NAME_MAX_LEN - 1)
+ nLen = MICROPROFILE_NAME_MAX_LEN - 1;
+ memcpy(&S.GroupInfo[S.nGroupCount].pName[0], pGroup, nLen);
+ S.GroupInfo[S.nGroupCount].pName[nLen] = '\0';
+ S.GroupInfo[S.nGroupCount].nNameLen = nLen;
+ S.GroupInfo[S.nGroupCount].nNumTimers = 0;
+ S.GroupInfo[S.nGroupCount].nGroupIndex = S.nGroupCount;
+ S.GroupInfo[S.nGroupCount].Type = Type;
+ S.GroupInfo[S.nGroupCount].nMaxTimerNameLen = 0;
+ S.GroupInfo[S.nGroupCount].nColor = 0x42;
+ S.GroupInfo[S.nGroupCount].nCategory = 0;
+ S.GroupInfo[S.nGroupCount].nWSNext = -2;
+
+ uint32_t nIndex = S.nGroupCount / 32;
+ uint32_t nBit = S.nGroupCount % 32;
+ {
+ S.CategoryInfo[0].nGroupMask[nIndex] |= (1 << nBit);
+ }
+ if(S.nStartEnabled)
+ {
+ S.nActiveGroupsWanted[nIndex] |= (1ll << nBit);
+ S.nActiveGroups[nIndex] |= (1ll << nBit);
+ S.AnyActive = true;
+ }
+ nGroupIndex = S.nGroupCount++;
+ S.nGroupMask[nIndex] |= (1 << nBit);
+ MP_ASSERT(S.nGroupCount < MICROPROFILE_MAX_GROUPS);
+ return nGroupIndex;
+}
+
+void MicroProfileRegisterGroup(const char* pGroup, const char* pCategory, uint32_t nColor)
+{
+ MicroProfileScopeLock L(MicroProfileMutex());
+
+ int nCategoryIndex = -1;
+ for(uint32_t i = 0; i < S.nCategoryCount; ++i)
+ {
+ if(!MP_STRCASECMP(pCategory, S.CategoryInfo[i].pName))
+ {
+ nCategoryIndex = (int)i;
+ break;
+ }
+ }
+ if(-1 == nCategoryIndex && S.nCategoryCount < MICROPROFILE_MAX_CATEGORIES)
+ {
+ MP_ASSERT(S.CategoryInfo[S.nCategoryCount].pName[0] == '\0');
+ nCategoryIndex = (int)S.nCategoryCount++;
+ uint32_t nLen = (uint32_t)strlen(pCategory);
+ if(nLen > MICROPROFILE_NAME_MAX_LEN - 1)
+ nLen = MICROPROFILE_NAME_MAX_LEN - 1;
+ memcpy(&S.CategoryInfo[nCategoryIndex].pName[0], pCategory, nLen);
+ S.CategoryInfo[nCategoryIndex].pName[nLen] = '\0';
+ }
+ uint16_t nGroup = MicroProfileGetGroup(pGroup, 0 != MP_STRCASECMP(pGroup, "gpu") ? MicroProfileTokenTypeCpu : MicroProfileTokenTypeGpu);
+ S.GroupInfo[nGroup].nColor = nColor;
+ if(nCategoryIndex >= 0)
+ {
+ uint32_t nIndex = nGroup / 32;
+ uint32_t nBit = nGroup % 32;
+ nBit = (1 << nBit);
+ uint32_t nOldCategory = S.GroupInfo[nGroup].nCategory;
+ S.CategoryInfo[nOldCategory].nGroupMask[nIndex] &= ~nBit;
+ S.CategoryInfo[nCategoryIndex].nGroupMask[nIndex] |= nBit;
+ S.GroupInfo[nGroup].nCategory = nCategoryIndex;
+ }
+}
+
+MicroProfileToken MicroProfileGetToken(const char* pGroup, const char* pName, uint32_t nColor, MicroProfileTokenType Type, uint32_t Flags)
+{
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ MicroProfileToken ret = MicroProfileFindTokenInternal(pGroup, pName);
+ if(ret != MICROPROFILE_INVALID_TOKEN)
+ {
+ int idx = MicroProfileGetTimerIndex(ret);
+ if(S.TimerInfo[idx].Flags & MICROPROFILE_TIMER_FLAG_PLACEHOLDER)
+ {
+ S.TimerInfo[idx].nColor = nColor & 0xffffff;
+ S.TimerInfo[idx].Flags = Flags;
+ S.TimerInfo[idx].Type = Type;
+ }
+ MP_ASSERT(S.TimerInfo[idx].Flags == Flags || (Flags & MICROPROFILE_TIMER_FLAG_PLACEHOLDER));
+ return ret;
+ }
+ uint16_t nGroupIndex = MicroProfileGetGroup(pGroup, Type);
+ uint16_t nTimerIndex = (uint16_t)(S.nTotalTimers++);
+ MP_ASSERT(nTimerIndex < MICROPROFILE_MAX_TIMERS);
+
+ uint32_t nBitIndex = nGroupIndex / 32;
+ uint32_t nBit = nGroupIndex % 32;
+ uint32_t nGroupMask = 1ll << nBit;
+ MicroProfileToken nToken = MicroProfileMakeToken(nGroupMask, (uint16_t)nBitIndex, nTimerIndex);
+ S.GroupInfo[nGroupIndex].nNumTimers++;
+ S.GroupInfo[nGroupIndex].nMaxTimerNameLen = MicroProfileMax(S.GroupInfo[nGroupIndex].nMaxTimerNameLen, (uint32_t)strlen(pName));
+ MP_ASSERT(S.GroupInfo[nGroupIndex].Type == Type); // dont mix cpu & gpu timers in the same group
+ S.nMaxGroupSize = MicroProfileMax(S.nMaxGroupSize, S.GroupInfo[nGroupIndex].nNumTimers);
+ S.TimerInfo[nTimerIndex].nToken = nToken;
+ uint32_t nLen = (uint32_t)strlen(pName);
+ if(nLen > MICROPROFILE_NAME_MAX_LEN - 1)
+ nLen = MICROPROFILE_NAME_MAX_LEN - 1;
+ memcpy(&S.TimerInfo[nTimerIndex].pName, pName, nLen);
+ snprintf(&S.TimerInfo[nTimerIndex].pNameExt[0], sizeof(S.TimerInfo[nTimerIndex].pNameExt) - 1, "%s %s", S.GroupInfo[nGroupIndex].pName, pName);
+ S.TimerInfo[nTimerIndex].pName[nLen] = '\0';
+ S.TimerInfo[nTimerIndex].nNameLen = nLen;
+ S.TimerInfo[nTimerIndex].nColor = nColor & 0xffffff;
+ S.TimerInfo[nTimerIndex].nGroupIndex = nGroupIndex;
+ S.TimerInfo[nTimerIndex].nTimerIndex = nTimerIndex;
+ S.TimerInfo[nTimerIndex].nWSNext = -2;
+ S.TimerInfo[nTimerIndex].Type = Type;
+ S.TimerInfo[nTimerIndex].Flags = Flags;
+ // printf("*** TOKEN %08d %s\\%s .. flags %08x\n", nTimerIndex, pGroup, pName, Flags);
+ S.TimerToGroup[nTimerIndex] = nGroupIndex;
+ return nToken;
+}
+
+void MicroProfileGetTokenC(MicroProfileToken* pToken, const char* pGroup, const char* pName, uint32_t nColor, MicroProfileTokenType Type, uint32_t flags)
+{
+ if(*pToken == MICROPROFILE_INVALID_TOKEN)
+ {
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ if(*pToken == MICROPROFILE_INVALID_TOKEN)
+ {
+ *pToken = MicroProfileGetToken(pGroup, pName, nColor, Type, flags);
+ }
+ }
+}
+
+const char* MicroProfileNextName(const char* pName, char* pNameOut, uint32_t* nSubNameLen)
+{
+ int nMaxLen = MICROPROFILE_NAME_MAX_LEN - 1;
+ const char* pRet = 0;
+ bool bDone = false;
+ uint32_t nChars = 0;
+ for(int i = 0; i < nMaxLen && !bDone; ++i)
+ {
+ char c = *pName++;
+ switch(c)
+ {
+ case 0:
+ bDone = true;
+ break;
+ case '\\':
+ case '/':
+ if(nChars)
+ {
+ bDone = true;
+ pRet = pName;
+ }
+ break;
+ default:
+ nChars++;
+ *pNameOut++ = c;
+ }
+ }
+ *nSubNameLen = nChars;
+ *pNameOut = '\0';
+ return pRet;
+}
+
+const char* MicroProfileCounterFullName(int nCounter)
+{
+ static char Buffer[1024];
+ int nNodes[32];
+ int nIndex = 0;
+ do
+ {
+ nNodes[nIndex++] = nCounter;
+ nCounter = S.CounterInfo[nCounter].nParent;
+ } while(nCounter >= 0);
+ int nOffset = 0;
+ while(nIndex >= 0 && nOffset < (int)sizeof(Buffer) - 2)
+ {
+ uint32_t nLen = S.CounterInfo[nNodes[nIndex]].nNameLen + nOffset; // < sizeof(Buffer)-1
+ nLen = MicroProfileMin((uint32_t)(sizeof(Buffer) - 2 - nOffset), nLen);
+ memcpy(&Buffer[nOffset], S.CounterInfo[nNodes[nIndex]].pName, nLen);
+
+ nOffset += S.CounterInfo[nNodes[nIndex]].nNameLen + 1;
+ if(nIndex)
+ {
+ Buffer[nOffset++] = '/';
+ }
+ nIndex--;
+ }
+ return &Buffer[0];
+}
+
+MicroProfileToken MicroProfileCounterTokenInit(int nParent, uint32_t nFlags)
+{
+ MP_ASSERT(0 == (nFlags & (~MICROPROFILE_COUNTER_FLAG_TYPE_MASK)));
+ MicroProfileToken nResult = S.nNumCounters++;
+ S.CounterInfo[nResult].nParent = nParent;
+ S.CounterInfo[nResult].nSibling = -1;
+ S.CounterInfo[nResult].nFirstChild = -1;
+ S.CounterInfo[nResult].nFlags = nFlags;
+ S.CounterInfo[nResult].eFormat = MICROPROFILE_COUNTER_FORMAT_DEFAULT;
+ S.CounterInfo[nResult].nLimit = 0;
+ S.CounterInfo[nResult].ExternalAtomic = 0;
+ S.CounterSource[nResult].pSource = 0;
+ S.CounterSource[nResult].nSourceSize = 0;
+ S.CounterInfo[nResult].nNameLen = 0;
+ S.CounterInfo[nResult].pName = nullptr;
+ S.CounterInfo[nResult].nWSNext = -2;
+ if(nParent >= 0)
+ {
+ MP_ASSERT(nParent < (int)S.nNumCounters);
+ S.CounterInfo[nResult].nSibling = S.CounterInfo[nParent].nFirstChild;
+ S.CounterInfo[nResult].nLevel = S.CounterInfo[nParent].nLevel + 1;
+ S.CounterInfo[nParent].nFirstChild = nResult;
+ }
+ else
+ {
+ S.CounterInfo[nResult].nLevel = 0;
+ }
+ return nResult;
+}
+void MicroProfileCounterTokenInitName(MicroProfileToken nToken, const char* pName)
+{
+ MP_ASSERT(0 == S.CounterInfo[nToken].pName);
+ S.CounterInfo[nToken].nNameLen = (uint16_t)strlen(pName);
+ S.CounterInfo[nToken].pName = MicroProfileStringInternLower(pName);
+}
+
+MicroProfileToken MicroProfileGetCounterTokenByParent(int nParent, const char* pName, uint32_t nFlags)
+{
+ for(uint32_t i = 0; i < S.nNumCounters; ++i)
+ {
+ if(nParent == S.CounterInfo[i].nParent && S.CounterInfo[i].pName == pName)
+ {
+ return i;
+ }
+ }
+ if(0 != (MICROPROFILE_COUNTER_FLAG_TOKEN_DONT_CREATE & nFlags))
+ return MICROPROFILE_INVALID_TOKEN;
+ MicroProfileToken nResult = MicroProfileCounterTokenInit(nParent, nFlags);
+ MicroProfileCounterTokenInitName(nResult, pName);
+ return nResult;
+}
+
+// by passing in last token/parent, and a non-changing static string,
+// we can quickly return in case the parent is the same as before.
+// Note that this doesn't support paths, but instead must be called once per level in the tree
+// String must be preinterned.
+MicroProfileToken MicroProfileCounterTokenTree(MicroProfileToken* LastToken, MicroProfileToken CurrentParent, const char* pString)
+{
+ MicroProfileToken Token = *LastToken;
+ if(Token != MICROPROFILE_INVALID_TOKEN)
+ {
+ if(S.CounterInfo[Token].pName == pString && S.CounterInfo[Token].nParent == CurrentParent)
+ {
+ return Token;
+ }
+ }
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ Token = MicroProfileGetCounterTokenByParent(CurrentParent, pString, 0);
+ *LastToken = Token;
+ return Token;
+}
+
+const char* MicroProfileCounterString(const char* pString)
+{
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ return MicroProfileStringInternLower(pString);
+}
+
+// Same as above, but works with non-static strings. always takes a lock, and does a search, so expect this to be not cheap
+MicroProfileToken MicroProfileCounterTokenTreeDynamic(MicroProfileToken* LastToken, MicroProfileToken Parent, const char* pString)
+{
+ (void)LastToken;
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ const char* pSubNameLower = MicroProfileStringInternLower(pString);
+ return MicroProfileGetCounterTokenByParent(Parent, pSubNameLower, 0);
+}
+
+MicroProfileToken MicroProfileGetCounterToken(const char* pName, uint32_t CounterFlag)
+{
+ MicroProfileInit();
+ MicroProfileScopeLock L(MicroProfileMutex());
+ char SubName[MICROPROFILE_NAME_MAX_LEN];
+ MicroProfileToken nResult = MICROPROFILE_INVALID_TOKEN;
+ do
+ {
+ uint32_t nLen = 0;
+ pName = MicroProfileNextName(pName, &SubName[0], &nLen);
+ if(0 == nLen)
+ {
+ break;
+ }
+ const char* pSubNameLower = MicroProfileStringInternLower(SubName);
+ nResult = MicroProfileGetCounterTokenByParent(nResult, pSubNameLower, 0);
+ if(MICROPROFILE_INVALID_TOKEN == nResult)
+ return nResult;
+
+ } while(pName != 0);
+ S.CounterInfo[nResult].nFlags |= MICROPROFILE_COUNTER_FLAG_LEAF;
+
+#if MICROPROFILE_COUNTER_HISTORY
+ if(CounterFlag & MICROPROFILE_COUNTER_FLAG_DOUBLE)
+ {
+ S.CounterInfo[nResult].nFlags |= MICROPROFILE_COUNTER_FLAG_DOUBLE;
+ S.dCounterMax[nResult] = -DBL_MAX;
+ S.dCounterMin[nResult] = DBL_MAX;
+ }
+#endif
+
+ MP_ASSERT((int)nResult >= 0);
+ return nResult;
+}
+
+MicroProfileToken MicroProfileGetChildCounterToken(MicroProfileToken Parent, const char* pName)
+{
+ MP_ASSERT(NULL == strpbrk(pName, "\\/")); // delimiters not supported when manually building the tree.
+ return MicroProfileCounterTokenTreeDynamic(nullptr, Parent, pName);
+}
+
+inline void MicroProfileLogPut(MicroProfileLogEntry LE, MicroProfileThreadLog* pLog)
+{
+ MP_ASSERT(pLog != 0); // this assert is hit if MicroProfileOnCreateThread is not called
+ MP_ASSERT(pLog->nActive == 1); // Dont put after calling thread exit
+ uint32_t nPut = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPut + 1) % MICROPROFILE_BUFFER_SIZE;
+ uint32_t nGet = pLog->nGet.load(std::memory_order_relaxed);
+ uint32_t nDistance = (nGet - nNextPos) % MICROPROFILE_BUFFER_SIZE;
+ MP_ASSERT(nDistance < MICROPROFILE_BUFFER_SIZE);
+ uint32_t nStackPut = pLog->nStackPut;
+ if(nDistance < nStackPut + 2)
+ {
+ S.nOverflow = 100;
+ }
+ else
+ {
+ pLog->Log[nPut] = LE;
+ pLog->nPut.store(nNextPos, std::memory_order_release);
+ }
+}
+
+inline uint64_t MicroProfileLogPutEnter(MicroProfileToken nToken_, uint64_t nTick, MicroProfileThreadLog* pLog)
+{
+ MP_ASSERT(pLog != 0); // this assert is hit if MicroProfileOnCreateThread is not called
+ MP_ASSERT(pLog->nActive == 1); // Dont put after calling thread exit
+ uint32_t nStackPut = pLog->nStackPut;
+ if(nStackPut < MICROPROFILE_STACK_MAX)
+ {
+ uint64_t LE = MicroProfileMakeLogIndex(MP_LOG_ENTER, nToken_, nTick);
+ uint32_t nPut = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPut + 1) % MICROPROFILE_BUFFER_SIZE;
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ uint32_t nDistance = (nGet - nNextPos) % MICROPROFILE_BUFFER_SIZE;
+ MP_ASSERT(nDistance < MICROPROFILE_BUFFER_SIZE);
+ if(nDistance < nStackPut + 4) // 2 for ring buffer, 2 for the actual entries
+ {
+ S.nOverflow = 100;
+ return MICROPROFILE_INVALID_TICK;
+ }
+ else
+ {
+#ifdef MICROPROFILE_VERIFY_BALANCED
+ pLog->VerifyStack[nStackPut] = LE;
+#endif
+ pLog->nStackPut = nStackPut + 1;
+ pLog->Log[nPut] = LE;
+ pLog->nPut.store(nNextPos, std::memory_order_release);
+ return nTick;
+ }
+ }
+ else
+ {
+ S.nOverflow = 100;
+ pLog->nStackPut = nStackPut + 1;
+ return MICROPROFILE_DROPPED_TICK;
+ }
+}
+
+inline uint64_t MicroProfileLogPutEnterCStr(const char* pStr, uint64_t nTick, MicroProfileThreadLog* pLog)
+{
+ MP_ASSERT(pLog != 0); // this assert is hit if MicroProfileOnCreateThread is not called
+ MP_ASSERT(pLog->nActive == 1); // Dont put after calling thread exit
+ uint32_t nStackPut = pLog->nStackPut;
+ if(nStackPut < MICROPROFILE_STACK_MAX)
+ {
+ uint64_t LE = MicroProfileMakeLogIndex(MP_LOG_ENTER, ETOKEN_CSTR_PTR, nTick);
+ uint64_t LEStr = MicroProfileMakeLogExtendedNoDataPtr((uint64_t)pStr);
+
+ MP_ASSERT(ETOKEN_CSTR_PTR == MicroProfileLogGetTimerIndex(LE));
+
+ uint32_t nPut = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPut + 2) % MICROPROFILE_BUFFER_SIZE;
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ uint32_t nDistance = (nGet - nNextPos) % MICROPROFILE_BUFFER_SIZE;
+ MP_ASSERT(nDistance < MICROPROFILE_BUFFER_SIZE);
+ if(nDistance < nStackPut + 6) // 2 for ring buffer, 4 for the actual entries
+ {
+ S.nOverflow = 100;
+ return MICROPROFILE_INVALID_TICK;
+ }
+ else
+ {
+ pLog->nStackPut = nStackPut + 1;
+ pLog->Log[nPut + 0] = LE;
+ pLog->Log[(nPut + 1) % MICROPROFILE_BUFFER_SIZE] = LEStr;
+ pLog->nPut.store(nNextPos, std::memory_order_release);
+ return nTick;
+ }
+ }
+ else
+ {
+ S.nOverflow = 100;
+ pLog->nStackPut = nStackPut + 1;
+ return MICROPROFILE_DROPPED_TICK;
+ }
+}
+inline void MicroProfileLogPutLeaveCStr(const char* pStr, uint64_t nTick, MicroProfileThreadLog* pLog)
+{
+ MP_ASSERT(pLog != 0); // this assert is hit if MicroProfileOnCreateThread is not called
+ MP_ASSERT(pLog->nActive);
+ MP_ASSERT(pLog->nStackPut != 0);
+ uint32_t nStackPut = --(pLog->nStackPut);
+ MP_ASSERT(nStackPut < 0xf0000000);
+ if(nStackPut < MICROPROFILE_STACK_MAX)
+ {
+ uint64_t LE = MicroProfileMakeLogIndex(MP_LOG_LEAVE, ETOKEN_CSTR_PTR, nTick);
+ uint64_t LEStr = MicroProfileMakeLogExtendedNoDataPtr((uint64_t)pStr);
+ MP_ASSERT(ETOKEN_CSTR_PTR == MicroProfileLogGetTimerIndex(LE));
+
+ uint32_t nPos = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPos + 2) % MICROPROFILE_BUFFER_SIZE;
+
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ MP_ASSERT(nStackPut < MICROPROFILE_STACK_MAX);
+ MP_ASSERT(nNextPos != nGet); // should never happen
+ pLog->Log[nPos + 0] = LE;
+ pLog->Log[(nPos + 1) % MICROPROFILE_BUFFER_SIZE] = LEStr;
+
+ pLog->nPut.store(nNextPos, std::memory_order_release);
+ }
+}
+
+inline void MicroProfileLogPutLeave(MicroProfileToken nToken_, uint64_t nTick, MicroProfileThreadLog* pLog)
+{
+ MP_ASSERT(pLog != 0); // this assert is hit if MicroProfileOnCreateThread is not called
+ MP_ASSERT(pLog->nActive);
+ MP_ASSERT(pLog->nStackPut != 0);
+ uint32_t nStackPut = --(pLog->nStackPut);
+ if(nStackPut < MICROPROFILE_STACK_MAX)
+ {
+ uint64_t LE = MicroProfileMakeLogIndex(MP_LOG_LEAVE, nToken_, nTick);
+ uint32_t nPos = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPos + 1) % MICROPROFILE_BUFFER_SIZE;
+
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ MP_ASSERT(nStackPut < MICROPROFILE_STACK_MAX);
+ MP_ASSERT(nNextPos != nGet); // should never happen
+
+#ifdef MICROPROFILE_VERIFY_BALANCED
+ // verify what we pop is what we push.
+ uint64_t Pushed = pLog->VerifyStack[nStackPut];
+ uint64_t TimerPopped = MicroProfileLogGetTimerIndex(LE);
+ uint64_t TimerOnStack = MicroProfileLogGetTimerIndex(Pushed);
+ if(TimerPopped != TimerOnStack)
+ {
+ uprintf("Push/Pop Mismatch %s vs %s\n", S.TimerInfo[TimerPopped].pName, S.TimerInfo[TimerOnStack].pName);
+ MP_ASSERT(0);
+ }
+#endif
+
+ pLog->Log[nPos] = LE;
+ pLog->nPut.store(nNextPos, std::memory_order_release);
+ }
+}
+
+inline void MicroProfileLogPut(MicroProfileToken nToken_, uint64_t nTick, uint64_t nBegin, MicroProfileThreadLog* pLog)
+{
+ MicroProfileLogPut(MicroProfileMakeLogIndex(nBegin, nToken_, nTick), pLog);
+}
+
+inline void MicroProfileLogPutGpu(MicroProfileLogEntry LE, MicroProfileThreadLogGpu* pLog)
+{
+ uint32_t nPos = pLog->nPut;
+ if(nPos < MICROPROFILE_GPU_BUFFER_SIZE)
+ {
+ pLog->Log[nPos] = LE;
+ pLog->nPut = nPos + 1;
+ }
+}
+
+inline void MicroProfileLogPutGpuTimer(MicroProfileToken nToken_, uint64_t nTick, uint64_t nBegin, MicroProfileThreadLogGpu* pLog)
+{
+ MicroProfileLogPutGpu(MicroProfileMakeLogIndex(nBegin, nToken_, nTick), pLog);
+}
+
+inline void MicroProfileLogPutGpuExtended(EMicroProfileTokenExtended eTokenExt, uint32_t nDataSizeQWords, uint32_t nPayload, MicroProfileThreadLogGpu* pLog)
+{
+ MicroProfileLogEntry LE = MicroProfileMakeLogExtended(eTokenExt, nDataSizeQWords, nPayload);
+ MicroProfileLogPutGpu(LE, pLog);
+}
+
+inline void MicroProfileLogPutGpuExtendedNoData(EMicroProfileTokenExtended eTokenExt, uint64_t nPayload, MicroProfileThreadLogGpu* pLog)
+{
+ MicroProfileLogEntry LE = MicroProfileMakeLogExtendedNoData(eTokenExt, nPayload);
+ MicroProfileLogPutGpu(LE, pLog);
+}
+
+uint32_t MicroProfileGroupTokenActive(MicroProfileToken nToken_)
+{
+ uint32_t nMask = MicroProfileGetGroupMask(nToken_);
+ uint32_t nIndex = MicroProfileGetGroupMaskIndex(nToken_);
+ return 0 != (S.nActiveGroups[nIndex] & nMask);
+}
+
+uint64_t MicroProfileEnterInternal(MicroProfileToken nToken_)
+{
+ if(MicroProfileGroupTokenActive(nToken_))
+ {
+ uint64_t nTick = MP_TICK();
+ if(MICROPROFILE_PLATFORM_MARKERS_ENABLED)
+ {
+ uint32_t idx = MicroProfileGetTimerIndex(nToken_);
+ MicroProfileTimerInfo& TI = S.TimerInfo[idx];
+ MICROPROFILE_PLATFORM_MARKER_BEGIN(TI.nColor, TI.pNameExt);
+ return nTick;
+ }
+ else
+ {
+ return MicroProfileLogPutEnter(nToken_, nTick, MicroProfileGetThreadLog2());
+ }
+ }
+ return MICROPROFILE_INVALID_TICK;
+}
+
+uint64_t MicroProfileEnterInternalCStr(const char* pStr)
+{
+ if(S.AnyActive)
+ {
+ uint64_t nTick = MP_TICK();
+ if(MICROPROFILE_PLATFORM_MARKERS_ENABLED)
+ {
+ MICROPROFILE_PLATFORM_MARKER_BEGIN(0, pStr);
+ return nTick;
+ }
+ else
+ {
+ return MicroProfileLogPutEnterCStr(pStr, nTick, MicroProfileGetThreadLog2());
+ }
+ }
+ return MICROPROFILE_INVALID_TICK;
+}
+
+void MicroProfileTimelineLeave(uint32_t id)
+{
+ if(!id)
+ return;
+ std::lock_guard Lock(MicroProfileTimelineMutex());
+ MicroProfileThreadLog* pLog = &S.TimelineLog;
+ uint32_t nPut = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPut + 1) % MICROPROFILE_BUFFER_SIZE;
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ uint32_t nDistance = (nGet - nNextPos) % MICROPROFILE_BUFFER_SIZE;
+
+ {
+ uint32_t nFrameStart = S.TimelineTokenFrameEnter[id % MICROPROFILE_TIMELINE_MAX_TOKENS];
+ uint32_t nFrameCurrent = S.nFrameCurrent;
+ if(nFrameCurrent < nFrameStart)
+ nFrameCurrent += MICROPROFILE_MAX_FRAME_HISTORY;
+ uint32_t nFrameDistance = (nFrameCurrent - nFrameStart) % MICROPROFILE_MAX_FRAME_HISTORY;
+
+ S.TimelineTokenFrameEnter[id % MICROPROFILE_TIMELINE_MAX_TOKENS] = MICROPROFILE_INVALID_FRAME;
+ S.TimelineTokenFrameLeave[id % MICROPROFILE_TIMELINE_MAX_TOKENS] = nFrameCurrent;
+
+ S.TimelineToken[id % MICROPROFILE_TIMELINE_MAX_TOKENS] = 0;
+ S.nTimelineFrameMax = MicroProfileMax(S.nTimelineFrameMax, nFrameDistance);
+ }
+
+ if(nDistance < 2 + 4)
+ {
+ S.nOverflow = 100;
+ }
+ else
+ {
+ uint64_t LEEnter = MicroProfileMakeLogIndex(MP_LOG_LEAVE, ETOKEN_CUSTOM_NAME, MP_TICK());
+ uint64_t LEId = MicroProfileMakeLogExtended(ETOKEN_CUSTOM_ID, 0, id);
+
+ pLog->Log[nPut++] = LEEnter;
+ nPut %= MICROPROFILE_BUFFER_SIZE;
+ pLog->Log[nPut++] = LEId;
+ nPut %= MICROPROFILE_BUFFER_SIZE;
+ pLog->nPut.store(nPut);
+ }
+}
+
+void MicroProfileTimelineEnterStatic(uint32_t nColor, const char* pStr)
+{
+ if(!S.AnyActive)
+ return;
+ uint32_t nToken = MicroProfileTimelineEnterInternal(nColor, pStr, (uint32_t)strlen(pStr), true);
+ (void)nToken;
+}
+void MicroProfileTimelineLeaveStatic(const char* pStr)
+{
+ if(!S.AnyActive)
+ return;
+
+ for(uint32_t i = 0; i < MICROPROFILE_TIMELINE_MAX_TOKENS; ++i)
+ {
+ if(S.TimelineTokenStaticString[i] && 0 == MP_STRCASECMP(pStr, S.TimelineTokenStaticString[i]))
+ {
+ MicroProfileTimelineLeave(S.TimelineToken[i]);
+ }
+ }
+}
+
+uint32_t MicroProfileTimelineEnterInternal(uint32_t nColor, const char* pStr, uint32_t nStrLen, int bIsStaticString)
+{
+ if(!S.AnyActive)
+ return 0;
+ std::lock_guard Lock(MicroProfileTimelineMutex());
+ MicroProfileThreadLog* pLog = &S.TimelineLog;
+ MP_ASSERT(pStr[nStrLen] == '\0');
+ nStrLen += 1;
+ uint32_t nStringQwords = MicroProfileGetQWordSize(nStrLen);
+ uint32_t nNumMessages = nStringQwords;
+
+ uint32_t nPut = pLog->nPut.load(std::memory_order_relaxed);
+ uint32_t nNextPos = (nPut + 1) % MICROPROFILE_BUFFER_SIZE;
+ uint32_t nGet = pLog->nGet.load(std::memory_order_acquire);
+ uint32_t nDistance = (nGet - nNextPos) % MICROPROFILE_BUFFER_SIZE;
+
+ if(nDistance < nNumMessages + 7)
+ {
+ S.nOverflow = 100;
+ return 0;
+ }
+ else
+ {
+
+ uint32_t token = pLog->nCustomId;
+ uint32_t nFrameLeave = S.TimelineTokenFrameLeave[token % MICROPROFILE_TIMELINE_MAX_TOKENS];
+ uint32_t nFrameEnter = S.TimelineTokenFrameEnter[token % MICROPROFILE_TIMELINE_MAX_TOKENS];
+ uint32_t nCounter = 0;
+ uint32_t nFrameCurrent = S.nFrameCurrent;
+ {
+
+ /// dont reuse tokens until their leave command has been dead for the maximum amount of frames we can generate a capture for.
+ while(token == 0 || nFrameEnter != MICROPROFILE_INVALID_FRAME || (nFrameCurrent - nFrameLeave < MICROPROFILE_MAX_FRAME_HISTORY + 3 && nFrameLeave != MICROPROFILE_INVALID_FRAME))
+ {
+ token = (uint32_t)pLog->nCustomId++;
+ nFrameLeave = S.TimelineTokenFrameLeave[token % MICROPROFILE_TIMELINE_MAX_TOKENS];
+ nFrameEnter = S.TimelineTokenFrameEnter[token % MICROPROFILE_TIMELINE_MAX_TOKENS];
+ if(++nCounter == MICROPROFILE_TIMELINE_MAX_TOKENS)
+ {
+ // MP_BREAK();
+ return 0;
+ }
+ }
+ S.TimelineTokenFrameEnter[token % MICROPROFILE_TIMELINE_MAX_TOKENS] = S.nFrameCurrent;
+ }
+ if(bIsStaticString)
+ {
+ S.TimelineTokenStaticString[token % MICROPROFILE_TIMELINE_MAX_TOKENS] = pStr;
+ }
+ else
+ {
+ S.TimelineTokenStaticString[token % MICROPROFILE_TIMELINE_MAX_TOKENS] = nullptr;
+ }
+ S.TimelineToken[token % MICROPROFILE_TIMELINE_MAX_TOKENS] = token;
+
+ uint64_t LEEnter = MicroProfileMakeLogIndex(MP_LOG_ENTER, ETOKEN_CUSTOM_NAME, MP_TICK());
+ uint64_t LEColor = MicroProfileMakeLogExtended(ETOKEN_CUSTOM_COLOR, 0, nColor);
+ uint64_t LEId = MicroProfileMakeLogExtended(ETOKEN_CUSTOM_ID, nStringQwords, token);
+
+ pLog->Log[nPut++] = LEEnter;
+ nPut %= MICROPROFILE_BUFFER_SIZE;
+ pLog->Log[nPut++] = LEColor;
+ nPut %= MICROPROFILE_BUFFER_SIZE;
+ pLog->Log[nPut++] = LEId;
+ nPut %= MICROPROFILE_BUFFER_SIZE;
+
+ // copy if we dont wrap
+ if(nPut + nStringQwords <= MICROPROFILE_BUFFER_SIZE)
+ {
+ memcpy(&pLog->Log[nPut], pStr, nStrLen + 1);
+ nPut += nStringQwords;
+ }
+ else
+ {
+ int nCharsLeft = (int)nStrLen;
+ while(nCharsLeft > 0)
+ {
+ int nCount = MicroProfileMin(nCharsLeft, 8);
+ memcpy(&pLog->Log[nPut++], pStr, nCount);
+ // uint64_t LEPayload = MicroProfileMakeLogPayload(pStr, nCount);
+ // pLog->Log[nPut++] = LEPayload; nPut %= MICROPROFILE_BUFFER_SIZE;
+ pStr += nCount;
+ nCharsLeft -= nCount;
+ }
+ }
+ pLog->nPut.store(nPut);
+ return token;
+ }
+}
+
+uint32_t MicroProfileTimelineEnter(uint32_t nColor, const char* pStr)
+{
+ return MicroProfileTimelineEnterInternal(nColor, pStr, (uint32_t)strlen(pStr), false);
+}
+
+uint32_t MicroProfileTimelineEnterf(uint32_t nColor, const char* pStr, ...)
+{
+ if(!S.AnyActive)
+ return 0;
+ char buffer[MICROPROFILE_MAX_STRING + 1];
+ va_list args;
+ va_start(args, pStr);
+#ifdef _WIN32
+ size_t size = vsprintf_s(buffer, pStr, args);
+#else
+ size_t size = vsnprintf(buffer, sizeof(buffer) - 1, pStr, args);
+#endif
+ va_end(args);
+ MP_ASSERT(size < sizeof(buffer));
+ buffer[size] = '\0';
+ return MicroProfileTimelineEnterInternal(nColor, buffer, (uint32_t)size, false);
+}
+
+void MicroProfileLocalCounterAdd(int64_t* pCounter, int64_t nCount)
+{
+ *pCounter += nCount;
+}
+int64_t MicroProfileLocalCounterSet(int64_t* pCounter, int64_t nCount)
+{
+ int64_t r = *pCounter;
+ *pCounter = nCount;
+ return r;
+}
+
+void MicroProfileLocalCounterAddAtomic(MicroProfileToken nToken, int64_t nCount)
+{
+ std::atomic* pCounter = &S.CounterInfo[nToken].ExternalAtomic;
+ pCounter->fetch_add(nCount);
+}
+int64_t MicroProfileLocalCounterSetAtomic(MicroProfileToken nToken, int64_t nCount)
+{
+
+ std::atomic