Merging r6145 through r6171 from trunk to ogl-es branch

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6172 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2020-12-19 15:03:11 +00:00
parent 01920bf808
commit fa0b1cb509
117 changed files with 8063 additions and 6758 deletions

@ -9,6 +9,9 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Add getActiveColor functions to IGUIStaticText and IGUIButton (get currently used color).
- Add IGUIEnvironment::addToDeletionQueue to allow save removal of gui elements while iterating over them (like the same named function in ISceneManager).
- IGUIEnvironment::drawAll has now a parameter to allow disabling automatic resize to screensize. Makes it easier to use partial screens with full alignment support.
- No longer try to set WM_QUIT when using an external Window on Win32. - No longer try to set WM_QUIT when using an external Window on Win32.
Thx @Marko Mahnic for the patch (https://sourceforge.net/p/irrlicht/bugs/449) Thx @Marko Mahnic for the patch (https://sourceforge.net/p/irrlicht/bugs/449)
- ply meshloader now also supports textures with uv-labels named texture_u/texture_v. - ply meshloader now also supports textures with uv-labels named texture_u/texture_v.
@ -22,15 +25,16 @@ Changes in 1.9 (not yet released)
- Improvements to B3D writer for speed, readability and handling of low framerate animations. - Improvements to B3D writer for speed, readability and handling of low framerate animations.
Thanks @JLouisB for the patch (For more info, see: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=50067&start=15) Thanks @JLouisB for the patch (For more info, see: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=50067&start=15)
- Add another render pass ESNRP_GUI which is drawn last and is p.E. useful for rendering gui nodes in the scenemanager. - Add another render pass ESNRP_GUI which is drawn last and is p.E. useful for rendering gui nodes in the scenemanager.
- BurningVideo: 0.51 - BurningVideo: 0.52
- 10 year anniversary update - 10 year anniversary update
- Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map]
- increased internal s4DVertex to support 4 Textures and 4 Colors [switchable] - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
- Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption
- 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D, scissor
- Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE] - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
- NormalMap for 1 Light accurate. still all lights are accumulated - NormalMap for 1 Light accurate. still all lights are accumulated
- SuperTuxKart 8.0.1 playable - SuperTuxKart 8.0.1 playable
- Internal Backbuffer Scaling and Interlacing
- Known Problems - Known Problems
- Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows - Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows
- Triangle MipMap Selection. Wrong for TextureAtlas and Billboards - Triangle MipMap Selection. Wrong for TextureAtlas and Billboards
@ -309,6 +313,7 @@ Changes in 1.9 (not yet released)
-------------------------- --------------------------
Changes in 1.8.5 Changes in 1.8.5
- Update libpng to 1.6.37 (from 1.6.23)
- Fix CIrrDeviceSDL::getVideoModeList which didn't return video modes before. Thx @kas1e for report and patch. - Fix CIrrDeviceSDL::getVideoModeList which didn't return video modes before. Thx @kas1e for report and patch.
- CIrrDeviceMacOSX now sets the SEvent.MouseInput Shift and Control values on mouse events like the other devices. Thanks @ Zero King for patch (#321) - CIrrDeviceMacOSX now sets the SEvent.MouseInput Shift and Control values on mouse events like the other devices. Thanks @ Zero King for patch (#321)
- isWindowFocused in IrrDeviceSDL device now returns the input focus like the other devices. Before it was returning a mouse-over-window state. - isWindowFocused in IrrDeviceSDL device now returns the input focus like the other devices. Before it was returning a mouse-over-window state.

@ -72,24 +72,14 @@ bool CMainMenu::run()
// add list box // add list box
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1); gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
const wchar_t* const names[] =
{L"Software Renderer", L"Burning's Video",
L"Direct3D 8", L"Direct3D 9", L"OpenGL 1.x-4.x",
L"OpenGL-ES 1.x", L"OpenGL-ES 2.x"};
for (u32 i=1; i<video::EDT_COUNT; ++i) for (u32 i=1; i<video::EDT_COUNT; ++i)
{ {
if (IrrlichtDevice::isDriverSupported(video::E_DRIVER_TYPE(i))) if (IrrlichtDevice::isDriverSupported(video::E_DRIVER_TYPE(i)))
box->addItem(names[i-1]); {
} box->addItem(core::stringw(video::DRIVER_TYPE_NAMES[i]).c_str());
if ( driverType == video::E_DRIVER_TYPE(i) )
switch (driverType ) selected = box->getItemCount()-1;
{ }
case video::EDT_OPENGL: selected = 0; break;
case video::EDT_DIRECT3D9: selected = 1; break;
case video::EDT_BURNINGSVIDEO: selected = 2; break;
case video::EDT_SOFTWARE: selected = 3; break;
default: break;
} }
box->setSelected(selected); box->setSelected(selected);

@ -26,23 +26,23 @@ namespace scene
//! Get the material of this meshbuffer //! Get the material of this meshbuffer
/** \return Material of this buffer. */ /** \return Material of this buffer. */
virtual video::SMaterial& getMaterial() =0; virtual video::SMaterial& getMaterial() _IRR_OVERRIDE_ =0;
//! Get the material of this meshbuffer //! Get the material of this meshbuffer
/** \return Material of this buffer. */ /** \return Material of this buffer. */
virtual const video::SMaterial& getMaterial() const =0; virtual const video::SMaterial& getMaterial() const _IRR_OVERRIDE_ =0;
//! Get the axis aligned bounding box of this meshbuffer. //! Get the axis aligned bounding box of this meshbuffer.
/** \return Axis aligned bounding box of this buffer. */ /** \return Axis aligned bounding box of this buffer. */
virtual const core::aabbox3df& getBoundingBox() const =0; virtual const core::aabbox3df& getBoundingBox() const _IRR_OVERRIDE_ =0;
//! Set axis aligned bounding box //! Set axis aligned bounding box
/** \param box User defined axis aligned bounding box to use /** \param box User defined axis aligned bounding box to use
for this buffer. */ for this buffer. */
virtual void setBoundingBox(const core::aabbox3df& box) =0; virtual void setBoundingBox(const core::aabbox3df& box) _IRR_OVERRIDE_ =0;
//! Recalculates the bounding box. Should be called if the mesh changed. //! Recalculates the bounding box. Should be called if the mesh changed.
virtual void recalculateBoundingBox() =0; virtual void recalculateBoundingBox() _IRR_OVERRIDE_ =0;
//! Append the vertices and indices to the current buffer //! Append the vertices and indices to the current buffer
/** Only works for compatible vertex types. /** Only works for compatible vertex types.

@ -139,6 +139,10 @@ namespace gui
/** \return: The override color */ /** \return: The override color */
virtual video::SColor getOverrideColor(void) const = 0; virtual video::SColor getOverrideColor(void) const = 0;
//! Gets the currently used text color
/** Either a skin-color for the current state or the override color */
virtual video::SColor getActiveColor() const = 0;
//! Sets if the button text should use the override color or the color in the gui skin. //! Sets if the button text should use the override color or the color in the gui skin.
/** \param enable: If set to true, the override color, which can be set /** \param enable: If set to true, the override color, which can be set
with IGUIStaticText::setOverrideColor is used, otherwise the with IGUIStaticText::setOverrideColor is used, otherwise the

@ -74,7 +74,9 @@ class IGUIEnvironment : public virtual IReferenceCounted
public: public:
//! Draws all gui elements by traversing the GUI environment starting at the root node. //! Draws all gui elements by traversing the GUI environment starting at the root node.
virtual void drawAll() = 0; /** \param When true ensure the GuiEnvironment (aka the RootGUIElement) has the same size as the current driver screensize.
Can be set to false to control that size yourself, p.E when not the full size should be used for UI. */
virtual void drawAll(bool useScreenSize=true) = 0;
//! Sets the focus to an element. //! Sets the focus to an element.
/** Causes a EGET_ELEMENT_FOCUS_LOST event followed by a /** Causes a EGET_ELEMENT_FOCUS_LOST event followed by a
@ -621,10 +623,10 @@ public:
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)=0; virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)=0;
//! writes an element //! writes an element
virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* node) =0; virtual void writeGUIElement(io::IXMLWriter* writer, IGUIElement* element) =0;
//! reads an element //! reads an element
virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* node) =0; virtual void readGUIElement(io::IXMLReader* reader, IGUIElement* element) =0;
//! Find the next element which would be selected when pressing the tab-key //! Find the next element which would be selected when pressing the tab-key
/** If you set the focus for the result you can manually force focus-changes like they /** If you set the focus for the result you can manually force focus-changes like they
@ -644,6 +646,17 @@ public:
//! Get the way the gui does handle focus changes //! Get the way the gui does handle focus changes
/** \returns A bitmask which is a combination of ::EFOCUS_FLAG flags.*/ /** \returns A bitmask which is a combination of ::EFOCUS_FLAG flags.*/
virtual u32 getFocusBehavior() const = 0; virtual u32 getFocusBehavior() const = 0;
//! Adds a IGUIElement to deletion queue.
/** Queued elements will be removed at the end of each drawAll call.
Or latest in the destructor of the GUIEnvironment.
This can be used to allow an element removing itself safely in a function
iterating over gui elements, like an overloaded IGUIElement::draw or
IGUIElement::OnPostRender function.
Note that in general just calling IGUIElement::remove() is enough.
Unless you create your own GUI elements removing themselves you won't need it.
\param element: Element to remove */
virtual void addToDeletionQueue(IGUIElement* element) = 0;
}; };

@ -51,6 +51,10 @@ namespace gui
/** \return: The override color */ /** \return: The override color */
virtual video::SColor getOverrideColor(void) const = 0; virtual video::SColor getOverrideColor(void) const = 0;
//! Gets the currently used text color
/** Either a skin-color for the current state or the override color */
virtual video::SColor getActiveColor() const = 0;
//! Sets if the static text should use the override color or the color in the gui skin. //! Sets if the static text should use the override color or the color in the gui skin.
/** \param enable: If set to true, the override color, which can be set /** \param enable: If set to true, the override color, which can be set
with IGUIStaticText::setOverrideColor is used, otherwise the with IGUIStaticText::setOverrideColor is used, otherwise the

@ -29,6 +29,9 @@ public:
//! constructor //! constructor
IImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, bool deleteMemory) : IImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, bool deleteMemory) :
Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false) Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false)
#if defined(IRRLICHT_sRGB)
,Format_sRGB(1)
#endif
{ {
BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8; BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
Pitch = BytesPerPixel * Size.Width; Pitch = BytesPerPixel * Size.Width;
@ -50,6 +53,18 @@ public:
return Format; return Format;
} }
#if defined(IRRLICHT_sRGB)
//! Texture is linear/sRGB (should be part of ColorFormat: default yes)
int get_sRGB() const
{
return Format_sRGB;
}
void set_sRGB(int val)
{
Format_sRGB = val;
}
#endif
//! Returns width and height of image data. //! Returns width and height of image data.
const core::dimension2d<u32>& getDimension() const const core::dimension2d<u32>& getDimension() const
{ {
@ -534,6 +549,22 @@ public:
return false; return false;
} }
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
static bool isRenderTargetOnlyFormat(const ECOLOR_FORMAT format)
{
switch (format)
{
case ECF_A1R5G5B5:
case ECF_R5G6B5:
case ECF_R8G8B8:
case ECF_A8R8G8B8:
return false;
default:
return true;
}
}
#endif
protected: protected:
ECOLOR_FORMAT Format; ECOLOR_FORMAT Format;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
@ -548,8 +579,12 @@ protected:
bool DeleteMipMapsMemory; bool DeleteMipMapsMemory;
core::irrAllocator<u8> Allocator; core::irrAllocator<u8> Allocator;
#if defined(IRRLICHT_sRGB)
int Format_sRGB;
#endif
}; };
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr

@ -698,7 +698,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
// store slopes in endpoint, and correct first pixel // store slopes in endpoint, and correct first pixel
@ -722,8 +722,8 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
} }
SOFTWARE_DRIVER_2_CLIPCHECK_REF; SOFTWARE_DRIVER_2_CLIPCHECK_REF;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i ) for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i )
{ {
@ -764,10 +764,10 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
// subTexel // subTexel
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
@ -807,7 +807,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
line.w[0] = a; line.w[0] = a;
line.w[1] = b; line.w[1] = b;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
a = (f32) pShader.i + subPixel; a = (f32) pShader.i + subPixel;
@ -863,9 +863,9 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y ); scan.invDeltaY[0] = fill_step_y( c->Pos.y - a->Pos.y );
scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y ); scan.invDeltaY[1] = fill_step_y( b->Pos.y - a->Pos.y );
scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y ); scan.invDeltaY[2] = fill_step_y( c->Pos.y - b->Pos.y );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -959,7 +959,7 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
} }
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0]; line.w[scan.left] = scan.w[0];
@ -1076,7 +1076,7 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
} }
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0]; line.w[scan.left] = scan.w[0];

@ -40,7 +40,7 @@ CDepthBuffer::~CDepthBuffer()
//! clears the zbuffer //! clears the zbuffer
void CDepthBuffer::clear(f32 value) void CDepthBuffer::clear(f32 value, interlaced_control interlaced)
{ {
ieee754 zMaxValue; ieee754 zMaxValue;
@ -50,7 +50,7 @@ void CDepthBuffer::clear(f32 value)
zMaxValue.f = value; zMaxValue.f = value;
#endif #endif
memset32 ( Buffer, zMaxValue.u, TotalSize ); memset32_interlaced(Buffer, zMaxValue.u, Pitch, Size.Height, interlaced);
} }
@ -66,9 +66,10 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer; delete [] Buffer;
Pitch = size.Width * sizeof ( fp24 ); Pitch = size.Width * sizeof ( fp24 );
TotalSize = Pitch * size.Height; size_t TotalSize = Pitch * size.Height;
Buffer = new u8[align_next(TotalSize,16)]; Buffer = new u8[align_next(TotalSize,16)];
clear ();
clear( 1.f, interlace_disabled());
} }
@ -107,7 +108,7 @@ CStencilBuffer::~CStencilBuffer()
//! clears the buffer //! clears the buffer
void CStencilBuffer::clear(u8 value) void CStencilBuffer::clear(u32 value, const interlaced_control interlaced)
{ {
u32 set = value; u32 set = value;
if (Bit == 8) if (Bit == 8)
@ -115,7 +116,7 @@ void CStencilBuffer::clear(u8 value)
set |= set << 8; set |= set << 8;
set |= set << 16; set |= set << 16;
} }
memset32 ( Buffer, set, TotalSize ); memset32_interlaced ( Buffer, set, Pitch,Size.Height,interlaced );
} }
@ -131,9 +132,10 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer; delete [] Buffer;
Pitch = size.Width * sizeof (tStencilSample); Pitch = size.Width * sizeof (tStencilSample);
TotalSize = Pitch * size.Height; size_t TotalSize = Pitch * size.Height;
Buffer = new u8[align_next(TotalSize,16)]; Buffer = new u8[align_next(TotalSize,16)];
clear ();
clear(0, interlace_disabled());
} }

@ -23,7 +23,7 @@ namespace video
virtual ~CDepthBuffer(); virtual ~CDepthBuffer();
//! clears the zbuffer //! clears the zbuffer
virtual void clear(f32 value=1.f) _IRR_OVERRIDE_; virtual void clear(f32 value, const interlaced_control interlaced) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_; virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -45,7 +45,6 @@ namespace video
u8* Buffer; u8* Buffer;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch; u32 Pitch;
}; };
@ -61,7 +60,7 @@ namespace video
virtual ~CStencilBuffer(); virtual ~CStencilBuffer();
//! clears the zbuffer //! clears the zbuffer
virtual void clear(u8 value=0) _IRR_OVERRIDE_; virtual void clear(u32 value, const interlaced_control interlaced) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_; virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -82,7 +81,6 @@ namespace video
private: private:
u8* Buffer; u8* Buffer;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch; u32 Pitch;
u32 Bit; u32 Bit;
}; };

@ -327,7 +327,7 @@ void CGUIButton::draw()
if (font) if (font)
font->draw(Text.c_str(), rect, font->draw(Text.c_str(), rect,
OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), getActiveColor(),
true, true, &AbsoluteClippingRect); true, true, &AbsoluteClippingRect);
} }
@ -466,6 +466,16 @@ video::SColor CGUIButton::getOverrideColor() const
return OverrideColor; return OverrideColor;
} }
irr::video::SColor CGUIButton::getActiveColor() const
{
if ( OverrideColorEnabled )
return OverrideColor;
IGUISkin* skin = Environment->getSkin();
if (skin)
return OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT);
return OverrideColor;
}
void CGUIButton::enableOverrideColor(bool enable) void CGUIButton::enableOverrideColor(bool enable)
{ {
OverrideColorEnabled = enable; OverrideColorEnabled = enable;

@ -50,6 +50,9 @@ namespace gui
//! Gets the override color //! Gets the override color
virtual video::SColor getOverrideColor(void) const _IRR_OVERRIDE_; virtual video::SColor getOverrideColor(void) const _IRR_OVERRIDE_;
//! Gets the currently used text color
virtual video::SColor getActiveColor() const _IRR_OVERRIDE_;
//! Sets if the button text should use the override color or the color in the gui skin. //! Sets if the button text should use the override color or the color in the gui skin.
virtual void enableOverrideColor(bool enable) _IRR_OVERRIDE_; virtual void enableOverrideColor(bool enable) _IRR_OVERRIDE_;

@ -136,10 +136,10 @@ void CGUIContextMenu::setSubMenu(u32 index, CGUIContextMenu* menu)
Items[index].SubMenu->drop(); Items[index].SubMenu->drop();
Items[index].SubMenu = menu; Items[index].SubMenu = menu;
menu->setVisible(false);
if (Items[index].SubMenu) if (menu)
{ {
menu->setVisible(false);
menu->AllowFocus = false; menu->AllowFocus = false;
if ( Environment->getFocus() == menu ) if ( Environment->getFocus() == menu )
{ {

@ -101,6 +101,8 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
//! destructor //! destructor
CGUIEnvironment::~CGUIEnvironment() CGUIEnvironment::~CGUIEnvironment()
{ {
clearDeletionQueue();
if ( HoveredNoSubelement && HoveredNoSubelement != this ) if ( HoveredNoSubelement && HoveredNoSubelement != this )
{ {
HoveredNoSubelement->drop(); HoveredNoSubelement->drop();
@ -191,19 +193,18 @@ void CGUIEnvironment::loadBuiltInFont()
//! draws all gui elements //! draws all gui elements
void CGUIEnvironment::drawAll() void CGUIEnvironment::drawAll(bool useScreenSize)
{ {
if (Driver) if (useScreenSize && Driver)
{ {
core::dimension2d<s32> dim(Driver->getScreenSize()); core::dimension2d<s32> dim(Driver->getScreenSize());
if (AbsoluteRect.LowerRightCorner.X != dim.Width || if (AbsoluteRect.LowerRightCorner.X != dim.Width ||
AbsoluteRect.LowerRightCorner.Y != dim.Height) AbsoluteRect.UpperLeftCorner.X != 0 ||
AbsoluteRect.LowerRightCorner.Y != dim.Height ||
AbsoluteRect.UpperLeftCorner.Y != 0
)
{ {
// resize gui environment setRelativePosition(core::recti(0,0,dim.Width, dim.Height));
DesiredRect.LowerRightCorner = dim;
AbsoluteClippingRect = DesiredRect;
AbsoluteRect = DesiredRect;
updateAbsolutePosition();
} }
} }
@ -213,6 +214,8 @@ void CGUIEnvironment::drawAll()
draw(); draw();
OnPostRender ( os::Timer::getTime () ); OnPostRender ( os::Timer::getTime () );
clearDeletionQueue();
} }
@ -471,6 +474,28 @@ void CGUIEnvironment::OnPostRender( u32 time )
IGUIElement::OnPostRender ( time ); IGUIElement::OnPostRender ( time );
} }
void CGUIEnvironment::addToDeletionQueue(IGUIElement* element)
{
if (!element)
return;
element->grab();
DeletionQueue.push_back(element);
}
void CGUIEnvironment::clearDeletionQueue()
{
if (DeletionQueue.empty())
return;
for (u32 i=0; i<DeletionQueue.size(); ++i)
{
DeletionQueue[i]->remove();
DeletionQueue[i]->drop();
}
DeletionQueue.clear();
}
// //
void CGUIEnvironment::updateHoveredElement(core::position2d<s32> mousePos) void CGUIEnvironment::updateHoveredElement(core::position2d<s32> mousePos)

@ -31,7 +31,7 @@ public:
virtual ~CGUIEnvironment(); virtual ~CGUIEnvironment();
//! draws all gui elements //! draws all gui elements
virtual void drawAll() _IRR_OVERRIDE_; virtual void drawAll(bool useScreenSize) _IRR_OVERRIDE_;
//! returns the current video driver //! returns the current video driver
virtual video::IVideoDriver* getVideoDriver() const _IRR_OVERRIDE_; virtual video::IVideoDriver* getVideoDriver() const _IRR_OVERRIDE_;
@ -269,8 +269,14 @@ public:
//! Get the way the gui does handle focus changes //! Get the way the gui does handle focus changes
virtual u32 getFocusBehavior() const _IRR_OVERRIDE_; virtual u32 getFocusBehavior() const _IRR_OVERRIDE_;
//! Adds a IGUIElement to deletion queue.
virtual void addToDeletionQueue(IGUIElement* element) _IRR_OVERRIDE_;
private: private:
//! clears the deletion queue
void clearDeletionQueue();
void updateHoveredElement(core::position2d<s32> mousePos); void updateHoveredElement(core::position2d<s32> mousePos);
void loadBuiltInFont(); void loadBuiltInFont();
@ -322,6 +328,8 @@ private:
IEventReceiver* UserReceiver; IEventReceiver* UserReceiver;
IOSOperator* Operator; IOSOperator* Operator;
u32 FocusFlags; u32 FocusFlags;
core::array<IGUIElement*> DeletionQueue;
static const io::path DefaultFontName; static const io::path DefaultFontName;
}; };

@ -203,17 +203,15 @@ void CGUIFont::setMaxHeight()
return; return;
MaxHeight = 0; MaxHeight = 0;
s32 t;
core::array< core::rect<s32> >& p = SpriteBank->getPositions(); core::array< core::rect<s32> >& p = SpriteBank->getPositions();
for (u32 i=0; i<p.size(); ++i) for (u32 i=0; i<p.size(); ++i)
{ {
t = p[i].getHeight(); const s32 t = p[i].getHeight();
if (t>MaxHeight) if (t>MaxHeight)
MaxHeight = t; MaxHeight = t;
} }
} }
void CGUIFont::pushTextureCreationFlags(bool(&flags)[3]) void CGUIFont::pushTextureCreationFlags(bool(&flags)[3])

@ -99,8 +99,8 @@ void CGUIStaticText::draw()
font->getDimension(Text.c_str()).Width; font->getDimension(Text.c_str()).Width;
} }
font->draw(Text.c_str(), frameRect, font->draw(Text.c_str(), frameRect,
OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), getActiveColor(),
HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, (RestrainTextInside ? &AbsoluteClippingRect : NULL)); HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
} }
else else
@ -129,7 +129,7 @@ void CGUIStaticText::draw()
} }
font->draw(BrokenText[i].c_str(), r, font->draw(BrokenText[i].c_str(), r,
OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT), getActiveColor(),
HAlign == EGUIA_CENTER, false, (RestrainTextInside ? &AbsoluteClippingRect : NULL)); HAlign == EGUIA_CENTER, false, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
r.LowerRightCorner.Y += height; r.LowerRightCorner.Y += height;
@ -254,6 +254,16 @@ video::SColor CGUIStaticText::getOverrideColor() const
} }
irr::video::SColor CGUIStaticText::getActiveColor() const
{
if ( OverrideColorEnabled )
return OverrideColor;
IGUISkin* skin = Environment->getSkin();
if (skin)
return OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT);
return OverrideColor;
}
//! Sets if the static text should use the override color or the //! Sets if the static text should use the override color or the
//! color in the gui skin. //! color in the gui skin.
void CGUIStaticText::enableOverrideColor(bool enable) void CGUIStaticText::enableOverrideColor(bool enable)

@ -66,6 +66,9 @@ namespace gui
//! Gets the override color //! Gets the override color
virtual video::SColor getOverrideColor() const _IRR_OVERRIDE_; virtual video::SColor getOverrideColor() const _IRR_OVERRIDE_;
//! Gets the currently used text color
virtual video::SColor getActiveColor() const _IRR_OVERRIDE_;
//! Sets if the static text should use the override color or the //! Sets if the static text should use the override color or the
//! color in the gui skin. //! color in the gui skin.
virtual void enableOverrideColor(bool enable) _IRR_OVERRIDE_; virtual void enableOverrideColor(bool enable) _IRR_OVERRIDE_;

@ -264,9 +264,7 @@ IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
{ {
IGUITreeViewNode* next = 0; IGUITreeViewNode* next = 0;
IGUITreeViewNode* node = 0; const IGUITreeViewNode* node = this;
node = const_cast<CGUITreeViewNode*>( this );
if( node->getExpanded() && node->hasChildren() ) if( node->getExpanded() && node->hasChildren() )
{ {
@ -756,10 +754,7 @@ bool CGUITreeView::OnEvent( const SEvent &event )
void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ ) void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ )
{ {
IGUITreeViewNode* oldSelected = Selected; IGUITreeViewNode* oldSelected = Selected;
IGUITreeViewNode* hitNode = 0;
s32 selIdx=-1; s32 selIdx=-1;
s32 n;
IGUITreeViewNode* node;
SEvent event; SEvent event;
event.EventType = EET_GUI_EVENT; event.EventType = EET_GUI_EVENT;
@ -776,9 +771,9 @@ void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ )
selIdx = ( ( ypos - 1 ) + scrollBarVPos ) / ItemHeight; selIdx = ( ( ypos - 1 ) + scrollBarVPos ) / ItemHeight;
} }
hitNode = 0; IGUITreeViewNode* hitNode = 0;
node = Root->getFirstChild(); IGUITreeViewNode* node = Root->getFirstChild();
n = 0; s32 n = 0;
while( node ) while( node )
{ {
if( selIdx == n ) if( selIdx == n )
@ -1026,7 +1021,7 @@ void CGUITreeView::draw()
iconWidth += ImageList->getImageSize().Width + 3; iconWidth += ImageList->getImageSize().Width + 3;
textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3; textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3;
} }
else if( ( IconFont && reinterpret_cast<CGUITreeViewNode*>( node )->Icon.size() ) else if( ( IconFont && static_cast<CGUITreeViewNode*>( node )->Icon.size() )
&& ( ( ImageLeftOfIcon && n == 1 ) && ( ( ImageLeftOfIcon && n == 1 )
|| ( !ImageLeftOfIcon && n == 0 ) ) ) || ( !ImageLeftOfIcon && n == 0 ) ) )
{ {

@ -131,39 +131,39 @@ namespace irr
} }
//! Changes the visible state of the mouse cursor. //! Changes the visible state of the mouse cursor.
virtual void setVisible(bool visible) virtual void setVisible(bool visible) _IRR_OVERRIDE_
{ {
IsVisible = visible; IsVisible = visible;
Device->setCursorVisible(visible); Device->setCursorVisible(visible);
} }
//! Returns if the cursor is currently visible. //! Returns if the cursor is currently visible.
virtual bool isVisible() const virtual bool isVisible() const _IRR_OVERRIDE_
{ {
return IsVisible; return IsVisible;
} }
//! Sets the new position of the cursor. //! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<f32> &pos) virtual void setPosition(const core::position2d<f32> &pos) _IRR_OVERRIDE_
{ {
setPosition(pos.X, pos.Y); setPosition(pos.X, pos.Y);
} }
//! Sets the new position of the cursor. //! Sets the new position of the cursor.
virtual void setPosition(f32 x, f32 y) virtual void setPosition(f32 x, f32 y) _IRR_OVERRIDE_
{ {
setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height)); setPosition((s32)(x*WindowSize.Width), (s32)(y*WindowSize.Height));
} }
//! Sets the new position of the cursor. //! Sets the new position of the cursor.
virtual void setPosition(const core::position2d<s32> &pos) virtual void setPosition(const core::position2d<s32> &pos) _IRR_OVERRIDE_
{ {
if (CursorPos.X != pos.X || CursorPos.Y != pos.Y) if (CursorPos.X != pos.X || CursorPos.Y != pos.Y)
setPosition(pos.X, pos.Y); setPosition(pos.X, pos.Y);
} }
//! Sets the new position of the cursor. //! Sets the new position of the cursor.
virtual void setPosition(s32 x, s32 y) virtual void setPosition(s32 x, s32 y) _IRR_OVERRIDE_
{ {
if (UseReferenceRect) if (UseReferenceRect)
{ {
@ -195,7 +195,7 @@ namespace irr
} }
//! Sets an absolute reference rect for calculating the cursor position. //! Sets an absolute reference rect for calculating the cursor position.
virtual void setReferenceRect(core::rect<s32>* rect=0) virtual void setReferenceRect(core::rect<s32>* rect=0) _IRR_OVERRIDE_
{ {
if (rect) if (rect)
{ {

@ -1076,7 +1076,7 @@ const wchar_t* CNullDriver::getName() const
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: Frist, draw all geometry. Then use this method, to draw the shadow //! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
{ {

@ -288,7 +288,7 @@ namespace video
virtual void addExternalImageWriter(IImageWriter* writer) _IRR_OVERRIDE_; virtual void addExternalImageWriter(IImageWriter* writer) _IRR_OVERRIDE_;
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: Frist, draw all geometry. Then use this method, to draw the shadow //! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles,
bool zfail=true, u32 debugDataVisible=0) _IRR_OVERRIDE_; bool zfail=true, u32 debugDataVisible=0) _IRR_OVERRIDE_;

File diff suppressed because it is too large Load Diff

@ -50,6 +50,18 @@ namespace video
virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_; const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
{
u16 flag = 0;
if (backBuffer) flag |= ECBF_COLOR;
if (zBuffer) flag |= ECBF_DEPTH;
return beginScene(flag, color, 1.f, 0, videoData, sourceRect);
}
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color);
#endif
virtual bool endScene() _IRR_OVERRIDE_; virtual bool endScene() _IRR_OVERRIDE_;
//! Only used by the internal engine. Used to notify the driver that //! Only used by the internal engine. Used to notify the driver that
@ -152,7 +164,12 @@ namespace video
//! Creates a render target texture. //! Creates a render target texture.
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size, virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_; const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
, const bool useStencil = false
#endif
) _IRR_OVERRIDE_;
virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_; virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;
@ -190,8 +207,10 @@ namespace video
//! Check if the driver supports creating textures with the given color format //! Check if the driver supports creating textures with the given color format
virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_;
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
//! Used by some SceneNodes to check if a material should be rendered in the transparent render pass //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass
virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_;
#endif
IDepthBuffer * getDepthBuffer () { return DepthBuffer; } IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
IStencilBuffer * getStencilBuffer () { return StencilBuffer; } IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
@ -252,6 +271,33 @@ namespace video
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_; virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
#endif
//! Get pointer to the IVideoDriver interface //! Get pointer to the IVideoDriver interface
/** \return Pointer to the IVideoDriver interface */ /** \return Pointer to the IVideoDriver interface */
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_; virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
@ -261,7 +307,7 @@ namespace video
void saveBuffer(); void saveBuffer();
//! sets a render target //! sets a render target
void setRenderTargetImage(video::CImage* image); void setRenderTargetImage2(video::IImage* color, video::IImage* depth=0, video::IImage* stencil=0);
//! sets the current Texture //! sets the current Texture
//bool setTexture(u32 stage, video::ITexture* texture); //bool setTexture(u32 stage, video::ITexture* texture);
@ -278,6 +324,7 @@ namespace video
video::ITexture* RenderTargetTexture; video::ITexture* RenderTargetTexture;
video::IImage* RenderTargetSurface; video::IImage* RenderTargetSurface;
core::dimension2d<u32> RenderTargetSize; core::dimension2d<u32> RenderTargetSize;
sVec4 RatioRenderTargetScreen; // Smaller Render Target
IBurningShader* CurrentShader; IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT]; IBurningShader* BurningShader[ETR2_COUNT];
@ -302,6 +349,8 @@ namespace video
ETS_COUNT_BURNING = 16 ETS_COUNT_BURNING = 16
}; };
// align manually to 16 byte start address
//u8 _pack_0[8];
enum E_TRANSFORMATION_FLAG enum E_TRANSFORMATION_FLAG
{ {
ETF_VALID = 1, ETF_VALID = 1,
@ -311,12 +360,12 @@ namespace video
ETF_TEXGEN_WRAP = 16, ETF_TEXGEN_WRAP = 16,
ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
}; };
core::matrix4 Transformation[2][ETS_COUNT_BURNING];
size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
size_t TransformationStack; // 0 .. 3D , 1 .. 2D size_t TransformationStack; // 0 .. 3D , 1 .. 2D
core::matrix4 ALIGN(16) Transformation[2][ETS_COUNT_BURNING];
size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture); void setRenderStates2DMode(const video::SColor& color,const video::ITexture* texture,bool useAlphaChannelOfTexture);
void setRenderStates3DMode(); void setRenderStates3DMode();
//ETS_CLIPSCALE, // moved outside to stay at 16 matrices //ETS_CLIPSCALE, // moved outside to stay at 16 matrices
@ -366,7 +415,7 @@ namespace video
//const is misleading. **v is const that true, but not *v.. //const is misleading. **v is const that true, but not *v..
f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const; f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;
s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, f32 dc_area, f32 lod_bias ) const; s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, const f32 dc_area, const f32 lod_bias ) const;
void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const; void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
void getCameraPosWorldSpace(); void getCameraPosWorldSpace();
@ -377,6 +426,20 @@ namespace video
//! Built-in 2D quad for 2D rendering. //! Built-in 2D quad for 2D rendering.
S3DVertex Quad2DVertices[4]; S3DVertex Quad2DVertices[4];
interlaced_control Interlaced;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
core::array<IRenderTarget*> RenderTargets;
inline bool getWriteZBuffer(const SMaterial& material) const
{
return material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent());
}
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData = 0)
{
return createDeviceDependentTexture(name, surface);
}
#endif
}; };

@ -20,6 +20,30 @@ namespace video
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB) //! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags); void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);
//nearest pow of 2 ( 257 will be 256 not 512 )
static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>& original, const u32 allowNonPowerOfTwo, const u32 maxSize)
{
u32 w, h;
if (allowNonPowerOfTwo)
{
w = original.Width;
h = original.Height;
}
else
{
w = 1;
while (w * 2 < original.Width) w *= 2;
if (w * 2 - original.Width < original.Width - w) w *= 2;
h = 1;
while (h * 2 < original.Height) h *= 2;
if (h * 2 - original.Height < original.Height - h) h *= 2;
}
if (maxSize && w > maxSize) w = maxSize;
if (maxSize && h > maxSize) h = maxSize;
return core::dimension2d<u32>(w, h);
}
//! constructor //! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver) CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)
: ITexture(name : ITexture(name
@ -27,24 +51,24 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
, ETT_2D , ETT_2D
#endif #endif
) )
,MipMapLOD(0), Flags(flags), Driver(driver) , MipMapLOD(0), Flags(flags), Driver(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSoftwareTexture2"); setDebugName("CSoftwareTexture2");
#endif #endif
#ifndef SOFTWARE_DRIVER_2_MIPMAPPING #if SOFTWARE_DRIVER_2_MIPMAPPING_MAX <= 1
Flags &= ~(GEN_MIPMAP| GEN_MIPMAP_AUTO); Flags &= ~(GEN_MIPMAP | GEN_MIPMAP_AUTO);
#endif #endif
//set baseclass properties //set baseclass properties
DriverType = EDT_BURNINGSVIDEO; DriverType = EDT_BURNINGSVIDEO;
ColorFormat = BURNINGSHADER_COLOR_FORMAT; ColorFormat = (Flags & IS_RENDERTARGET) ? SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT : SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT;
IsRenderTarget = (Flags & IS_RENDERTARGET) != 0; IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;
HasMipMaps = (Flags & GEN_MIPMAP) != 0; HasMipMaps = (Flags & GEN_MIPMAP) != 0;
MipMap0_Area[0] = 1; MipMap0_Area[0] = 1;
MipMap0_Area[1] = 1; MipMap0_Area[1] = 1;
LodBIAS = 0.75f; LodBIAS = 1.f;
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0; for (size_t i = 0; i < array_size(MipMap); ++i) MipMap[i] = 0;
if (!image) return; if (!image) return;
OriginalSize = image->getDimension(); OriginalSize = image->getDimension();
@ -52,7 +76,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0); if (Flags & IMAGE_IS_LINEAR) image->set_sRGB(0);
#else #else
//guessing linear image //guessing linear image
if (name.find("light") >= 0 || if (name.find("light") >= 0 ||
@ -72,47 +96,65 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//visual studio code warning //visual studio code warning
u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE; u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;
core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
if (IsRenderTarget && name.find("RaceGUI::markers") >= 0)
{
maxTexSize = 0;
}
#endif
/*
core::dimension2d<u32> optSize(OriginalSize.getOptimalSize(
(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo (Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
false, // requireSquare false, // requireSquare
(Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger (Flags & ALLOW_NPOT) ? 1 : maxTexSize == SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, // larger
(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue (Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
) )
); );
*/
core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize));
if (OriginalSize == optSize) if (OriginalSize == optSize)
{ {
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension()); MipMap[0] = new CImage(ColorFormat, image->getDimension());
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() ); MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
#endif #endif
if (!isCompressed) if (!isCompressed && image->getData())
image->copyTo(MipMap[0]); image->copyTo(MipMap[0]);
} }
else else
{ {
char buf[256]; MipMap[0] = new CImage(ColorFormat, optSize);
core::stringw showName ( name );
snprintf_irr ( buf, sizeof(buf), "Burningvideo: Warning Texture %ls reformat %ux%u,%d -> %ux%u,%d",
showName.c_str(),
OriginalSize.Width, OriginalSize.Height, OriginalColorFormat,
optSize.Width, optSize.Height,BURNINGSHADER_COLOR_FORMAT
);
os::Printer::log ( buf, ELL_WARNING );
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() ); MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
#endif #endif
if (!isCompressed) if (!isCompressed)
{ {
//image->copyToScalingBoxFilter ( MipMap[0],0, false ); //image->copyToScalingBoxFilter ( MipMap[0],0, false );
Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0, Flags); Resample_subSampling(BLITTER_TEXTURE, MipMap[0], 0, image, 0, Flags);
} }
// if Original Size is used for calculation ( 2D position, font) it will be wrong // if Original Size is used for calculation ( 2D position, font) it will be wrong
//OriginalSize = optSize; //OriginalSize = optSize;
} }
// Show Information about resizing
if (OriginalSize != optSize ||
( OriginalColorFormat != ColorFormat &&
!((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8)
)
)
{
char buf[256];
core::stringw showName(name);
snprintf_irr(buf, sizeof(buf), "Burningvideo: Texture '%ls' reformat %ux%u,%s -> %ux%u,%s",
showName.c_str(),
OriginalSize.Width, OriginalSize.Height, ColorFormatNames[OriginalColorFormat],
optSize.Width, optSize.Height, ColorFormatNames[ColorFormat]
);
os::Printer::log(buf, ELL_DEBUG);
}
//select highest mipmap 0 //select highest mipmap 0
regenerateMipMapLevels(image->getMipMapsData()); regenerateMipMapLevels(image->getMipMapsData());
} }
@ -121,9 +163,9 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//! destructor //! destructor
CSoftwareTexture2::~CSoftwareTexture2() CSoftwareTexture2::~CSoftwareTexture2()
{ {
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (size_t i = 0; i < array_size(MipMap); ++i)
{ {
if ( MipMap[i] ) if (MipMap[i])
{ {
MipMap[i]->drop(); MipMap[i]->drop();
MipMap[i] = 0; MipMap[i] = 0;
@ -132,7 +174,6 @@ CSoftwareTexture2::~CSoftwareTexture2()
} }
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
@ -141,12 +182,12 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
void CSoftwareTexture2::regenerateMipMapLevels(void* data) void CSoftwareTexture2::regenerateMipMapLevels(void* data)
#endif #endif
{ {
int i; size_t i;
// release // release
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (i = 1; i < array_size(MipMap); ++i)
{ {
if ( MipMap[i] ) if (MipMap[i])
{ {
MipMap[i]->drop(); MipMap[i]->drop();
MipMap[i] = 0; MipMap[i] = 0;
@ -155,10 +196,10 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
core::dimension2d<u32> newSize; core::dimension2d<u32> newSize;
if (HasMipMaps && ( (Flags & GEN_MIPMAP_AUTO) || 0 == data ) ) if (HasMipMaps && ((Flags & GEN_MIPMAP_AUTO) || 0 == data))
{ {
//need memory also if autogen mipmap disabled //need memory also if autogen mipmap disabled
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 1; i < array_size(MipMap); ++i)
{ {
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension(); const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic //isotropic
@ -167,7 +208,7 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (upperDim == newSize) if (upperDim == newSize)
break; break;
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB()); MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());
#endif #endif
@ -192,13 +233,13 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (origSize.Height > 1) origSize.Height >>= 1; if (origSize.Height > 1) origSize.Height >>= 1;
mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height); mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
i += 1; i += 1;
} while ((origSize.Width != 1 || origSize.Height != 1) && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX); } while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap));
//TODO: this is not true //TODO: this is not true
LodBIAS = i*0.75f; LodBIAS = i * 2.f;
origSize = OriginalSize; origSize = OriginalSize;
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && mip_current < mip_end; ++i) for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i)
{ {
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension(); const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic //isotropic
@ -210,10 +251,10 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (origSize.Width > 1) origSize.Width >>= 1; if (origSize.Width > 1) origSize.Width >>= 1;
if (origSize.Height > 1) origSize.Height >>= 1; if (origSize.Height > 1) origSize.Height >>= 1;
if (OriginalColorFormat != BURNINGSHADER_COLOR_FORMAT) if (OriginalColorFormat != ColorFormat)
{ {
IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false); IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
if (origSize == newSize) if (origSize == newSize)
tmpImage->copyTo(MipMap[i]); tmpImage->copyTo(MipMap[i]);
else else
@ -223,11 +264,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
else else
{ {
if (origSize == newSize) if (origSize == newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mip_current, false); MipMap[i] = new CImage(ColorFormat, newSize, mip_current, false);
else else
{ {
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mip_current, true, false); IImage* tmpImage = new CImage(ColorFormat, origSize, mip_current, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]); tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop(); tmpImage->drop();
} }
@ -238,33 +279,33 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
//visualize mipmap //visualize mipmap
for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 1; i < 0 && i < array_size(MipMap); ++i)
{ {
/*
static u32 color[] = { static u32 color[] = {
0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00, 0xFFFF0000,
0x300080bf,0x30bf4000,0x300040bf,0x307f00bf, 0xFFFF0000,0xFF00FF00,0xFF0000FF,
0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00, 0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,
0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf 0xFFff6600,0xFF00ff66,0xFF6600FF,
}; 0xFF66ff00,0xFF0066ff,0xFFff0066,
*/ 0xFF33ff00,0xFF0033ff,0xFF3300ff,
static u32 color[] = { 0xFF0000FF,0xFF0000FF,0xFF0000FF
0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,
0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF
}; };
if ( MipMap[i] ) if (MipMap[i])
{ {
core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension()); int border = 0;
const core::dimension2du& d = MipMap[i]->getDimension();
core::rect<s32> p(0, 0, d.Width, d.Height);
SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000); SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);
core::rect<s32> dclip(border, border, d.Width - border, d.Height - border);
Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], &dclip, 0, MipMap[i], &p, c.color);
} }
} }
//save mipmap chain //save mipmap chain
if ( 0 ) if (0)
{ {
char buf[256]; char buf[256];
const char* name = getName().getPath().c_str(); const char* name = getName().getPath().c_str();
@ -273,15 +314,15 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
i = 0; i = 0;
while (name[i]) while (name[i])
{ {
if (name[i] == '/' || name[i] == '\\') filename = i + 1; if (name[i] == '/' || name[i] == '\\') filename = (s32)i + 1;
//if (name[i] == '.') ext = i; //if (name[i] == '.') ext = i;
i += 1; i += 1;
} }
for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 0; i < array_size(MipMap); ++i)
{ {
if (MipMap[i]) if (MipMap[i])
{ {
snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i); snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, (s32)i);
Driver->writeImageToFile(MipMap[i], buf); Driver->writeImageToFile(MipMap[i], buf);
} }
} }
@ -300,12 +341,16 @@ void CSoftwareTexture2::calcDerivative()
MipMap0_Area[0] = dim.Width; MipMap0_Area[0] = dim.Width;
MipMap0_Area[1] = dim.Height; // screensize of a triangle MipMap0_Area[1] = dim.Height; // screensize of a triangle
//TA: try to mimic openGL mipmap. ( don't do this!)
//if (MipMap0_Area[0] < 32) MipMap0_Area[0] = 32;
//if (MipMap0_Area[1] < 32) MipMap0_Area[1] = 32;
Size = dim; // MipMap[MipMapLOD]->getDimension(); Size = dim; // MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch(); Pitch = MipMap[MipMapLOD]->getPitch();
} }
//preCalc mipmap texel center boundaries //preCalc mipmap texel center boundaries
for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (size_t i = 0; i < array_size(MipMap); ++i)
{ {
CSoftwareTexture2_Bound& b = TexBound[i]; CSoftwareTexture2_Bound& b = TexBound[i];
if (MipMap[i]) if (MipMap[i])
@ -335,7 +380,7 @@ void CSoftwareTexture2::calcDerivative()
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver) CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
, IRenderTarget(0) , IRenderTarget(0)
#endif #endif
{ {
DriverType = EDT_BURNINGSVIDEO; DriverType = EDT_BURNINGSVIDEO;
@ -378,12 +423,6 @@ void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& texture, I
} }
} }
ITexture* CSoftwareRenderTarget2::getTexture() const
{
return Texture[0];
}
static const float srgb_8bit_to_linear_float[1 << 8] = { static const float srgb_8bit_to_linear_float[1 << 8] = {
0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f, 0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,
@ -474,7 +513,7 @@ u32 linear_to_srgb_8bit(const float v)
ieee754 c; ieee754 c;
c.f = v; c.f = v;
const size_t x = c.u; const size_t x = c.u;
const u32 *table = (u32*)srgb_8bit_to_linear_float; const u32* table = (u32*)srgb_8bit_to_linear_float;
u32 y = 0; u32 y = 0;
y += table[y + 128] <= x ? 128 : 0; y += table[y + 128] <= x ? 128 : 0;
y += table[y + 64] <= x ? 64 : 0; y += table[y + 64] <= x ? 64 : 0;
@ -497,7 +536,7 @@ struct absrect2
s32 y1; s32 y1;
}; };
static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b) static inline int clipTest(absrect2& o, const core::rect<s32>* a, const absrect2& b)
{ {
if (a == 0) if (a == 0)
{ {
@ -522,19 +561,19 @@ static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB) //! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
// todo: texture jumps (mip selection problem) // todo: texture jumps (mip selection problem)
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,
const video::IImage* src, const core::rect<s32>* srcRect,size_t flags) const video::IImage* src, const core::rect<s32>* srcRect, size_t flags)
{ {
u8* dstData = (u8*)dst->getData();
const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height }; const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };
absrect2 dc; absrect2 dc;
if (clipTest(dc, dstRect, dst_clip)) return; if (clipTest(dc, dstRect, dst_clip) || !dstData) return;
const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat(); const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();
u8* dstData = (u8*)dst->getData();
const u8* srcData = (u8*)src->getData();
const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height }; const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };
absrect2 sc; absrect2 sc;
if (clipTest(sc, srcRect, src_clip)) return; if (clipTest(sc, srcRect, src_clip) || !srcData) return;
const video::ECOLOR_FORMAT srcFormat = src->getColorFormat(); const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();
const u8* srcData = (u8*)src->getData();
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
const int dst_sRGB = dst->get_sRGB(); const int dst_sRGB = dst->get_sRGB();
@ -560,14 +599,14 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
for (int dy = dc.y0; dy < dc.y1; ++dy) for (int dy = dc.y0; dy < dc.y1; ++dy)
{ {
f[1] = f[3]; f[1] = f[3];
f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1]; f[3] = sc.y0 + (dy + 1 - dc.y0) * scale[1];
if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
f[2] = (float)sc.x0; f[2] = (float)sc.x0;
for (int dx = dc.x0; dx < dc.x1; ++dx) for (int dx = dc.x0; dx < dc.x1; ++dx)
{ {
f[0] = f[2]; f[0] = f[2];
f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0]; f[2] = sc.x0 + (dx + 1 - dc.x0) * scale[0];
if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f; if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
//accumulate linear color //accumulate linear color
@ -599,12 +638,12 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
switch (srcFormat) switch (srcFormat)
{ {
case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break; case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy * src_clip.x1) * 2 + (fx * 2))); break;
case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break; case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy * src_clip.x1) * 2 + (fx * 2))); break;
case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy*src_clip.x1) * 4 + (fx * 4)); break; case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy * src_clip.x1) * 4 + (fx * 4)); break;
case video::ECF_R8G8B8: case video::ECF_R8G8B8:
{ {
const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3); const u8* p = srcData + (fy * src_clip.x1) * 3 + (fx * 3);
sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2]; sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];
} break; } break;
default: break; default: break;
@ -650,16 +689,16 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
} }
switch (dstFormat) switch (dstFormat)
{ {
case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break; case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy * dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;
case video::ECF_R8G8B8: case video::ECF_R8G8B8:
{ {
u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3); u8* p = dstData + (dy * dst_clip.x1) * 3 + (dx * 3);
p[2] = (sbgra) & 0xFF; p[2] = (sbgra) & 0xFF;
p[1] = (sbgra >> 8) & 0xFF; p[1] = (sbgra >> 8) & 0xFF;
p[0] = (sbgra >> 16) & 0xFF; p[0] = (sbgra >> 16) & 0xFF;
} break; } break;
case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break; case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy * dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;
case video::ECF_R5G6B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break; case video::ECF_R5G6B5: *(u16*)(dstData + (dy * dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;
default: default:
break; break;
} }

@ -8,7 +8,11 @@
#include "SoftwareDriver2_compile_config.h" #include "SoftwareDriver2_compile_config.h"
#include "ITexture.h" #include "ITexture.h"
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#include "IVideoDriver.h"
#else
#include "IRenderTarget.h" #include "IRenderTarget.h"
#endif
#include "CImage.h" #include "CImage.h"
namespace irr namespace irr
@ -51,14 +55,18 @@ public:
u32 getMipmapLevel(s32 newLevel) const u32 getMipmapLevel(s32 newLevel) const
{ {
if ( newLevel < 0 ) newLevel = 0; if ( newLevel < 0 ) newLevel = 0;
else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1; else if ( newLevel >= (s32)array_size(MipMap)) newLevel = array_size(MipMap) - 1;
while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1; while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;
return newLevel; return newLevel;
} }
//! lock function //! lock function
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
#else
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_ virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
#endif
{ {
if (Flags & GEN_MIPMAP) if (Flags & GEN_MIPMAP)
{ {
@ -75,18 +83,20 @@ public:
virtual void unlock() _IRR_OVERRIDE_ virtual void unlock() _IRR_OVERRIDE_
{ {
} }
/*
//! compare the area drawn with the area of the texture //! compare the area drawn with the area of the texture
f32 getLODFactor( const f32 texArea ) const f32 getLODFactor( const f32 texArea ) const
{ {
return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea; return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
//return MipMap[0]->getImageDataSizeInPixels () * texArea; //return MipMap[0]->getImageDataSizeInPixels () * texArea;
} }
*/
const u32* getMipMap0_Area() const const u32* getMipMap0_Area() const
{ {
return MipMap0_Area; return MipMap0_Area;
} }
f32 get_lod_bias() const { return LodBIAS; }
//! returns unoptimized surface (misleading name. burning can scale down originalimage) //! returns unoptimized surface (misleading name. burning can scale down originalimage)
virtual CImage* getImage() const virtual CImage* getImage() const
@ -106,9 +116,33 @@ public:
return TexBound[MipMapLOD]; return TexBound[MipMapLOD];
} }
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_; virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
#else
virtual void regenerateMipMapLevels(void* data = 0);
#endif
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; };
const core::dimension2d<u32>& getSize() const { return Size; };
E_DRIVER_TYPE getDriverType() const { return DriverType; };
ECOLOR_FORMAT getColorFormat() const { return ColorFormat; };
ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; };
u32 getPitch() const { return Pitch; };
bool hasMipMaps() const { return HasMipMaps; }
bool isRenderTarget() const { return IsRenderTarget; }
core::dimension2d<u32> OriginalSize;
core::dimension2d<u32> Size;
E_DRIVER_TYPE DriverType;
ECOLOR_FORMAT OriginalColorFormat;
ECOLOR_FORMAT ColorFormat;
u32 Pitch;
bool HasMipMaps;
bool IsRenderTarget;
#endif
f32 get_lod_bias() const { return LodBIAS; }
private: private:
void calcDerivative(); void calcDerivative();
@ -120,7 +154,7 @@ private:
CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
u32 MipMap0_Area[2]; u32 MipMap0_Area[2];
f32 LodBIAS; f32 LodBIAS; // Tweak mipmap selection
}; };
/*! /*!
@ -134,7 +168,10 @@ public:
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_; virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_;
ITexture* getTexture() const; #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
E_DRIVER_TYPE DriverType;
core::array<ITexture*> Texture;
#endif
protected: protected:
CBurningVideoDriver* Driver; CBurningVideoDriver* Driver;

@ -87,7 +87,7 @@ public:
//virtual bool canWireFrame () { return true; } //virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
@ -104,7 +104,7 @@ CTRGouraud2::CTRGouraud2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraud2::scanline_bilinear () void CTRGouraud2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ void CTRGouraud2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -196,10 +196,11 @@ void CTRGouraud2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
//if test active only first pixel //if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
#endif #endif
@ -384,8 +385,9 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -416,7 +418,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -511,7 +513,6 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -545,8 +546,9 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -577,7 +579,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -105,7 +105,7 @@ CTRGouraudAlpha2::CTRGouraudAlpha2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudAlpha2::scanline_bilinear () void CTRGouraudAlpha2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -148,7 +148,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -204,7 +204,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -270,9 +270,9 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -397,7 +397,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -428,7 +428,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -522,7 +522,6 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -557,7 +556,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -588,7 +587,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
//! constructor //! constructor
@ -104,7 +104,7 @@ CTRGouraudAlphaNoZ2::CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudAlphaNoZ2::scanline_bilinear () void CTRGouraudAlphaNoZ2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -144,7 +144,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -201,7 +201,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -271,9 +271,9 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -397,7 +397,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -428,7 +428,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -557,7 +557,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -588,7 +588,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -87,7 +87,7 @@ public:
virtual bool canWireFrame () { return true; } virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
//! constructor //! constructor
@ -103,7 +103,7 @@ CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudNoZ2::scanline_bilinear () void CTRGouraudNoZ2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -142,7 +142,7 @@ void CTRGouraudNoZ2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -195,9 +195,9 @@ void CTRGouraudNoZ2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -383,8 +383,10 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -415,7 +417,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -509,7 +511,6 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -542,9 +543,10 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -575,7 +577,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -164,7 +164,7 @@ void CTRNormalMap::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -254,7 +254,7 @@ void CTRNormalMap::fragmentShader()
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -400,9 +400,9 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -572,7 +572,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -618,7 +618,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -751,7 +751,6 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -801,7 +800,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -847,7 +846,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
fragmentShader(); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -139,7 +139,7 @@ void CTRStencilShadow::fragmentShader()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -174,7 +174,7 @@ void CTRStencilShadow::fragmentShader()
#endif #endif
s32 i; s32 i;
for (i = 0; i <= dx; i++) for (i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -226,9 +226,9 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -382,7 +382,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -423,7 +423,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -545,7 +545,6 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -590,7 +589,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -631,7 +630,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -87,22 +87,6 @@ namespace video
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_; virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_; virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1)
virtual void setZCompareFunc(u32 func)
{
depth_func = (E_COMPARISON_FUNC)func;
}
virtual void setParam(u32 index, f32 value)
{
SBurningShaderMaterial material;
material.org.ZBuffer = depth_func;
material.org.MaterialTypeParam = value;
OnSetMaterial(material);
}
#endif
private: private:
// fragment shader // fragment shader
typedef void (CTRTextureBlend::*tFragmentShader) (); typedef void (CTRTextureBlend::*tFragmentShader) ();
@ -269,7 +253,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -325,7 +309,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -368,7 +352,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -454,7 +438,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -514,7 +498,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -561,7 +545,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -649,7 +633,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2 ( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -707,7 +691,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -757,7 +741,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -850,7 +834,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -908,7 +892,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -957,7 +941,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1050,7 +1034,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1108,7 +1092,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1174,7 +1158,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1280,7 +1264,7 @@ void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1337,7 +1321,7 @@ void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for (i = 0; i <= dx; ++i) for (i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if (line.w[0] >= z[i]) if (line.w[0] >= z[i])
@ -1434,7 +1418,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1492,7 +1476,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1541,7 +1525,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1633,7 +1617,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1691,7 +1675,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1739,7 +1723,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1830,7 +1814,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1888,7 +1872,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1937,7 +1921,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -2030,7 +2014,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -2088,7 +2072,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -2137,7 +2121,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -2202,9 +2186,9 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -2328,7 +2312,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -2359,7 +2343,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
(this->*fragmentShader) (); interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -2453,7 +2437,6 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -2488,7 +2471,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -2519,7 +2502,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
(this->*fragmentShader) (); interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
virtual bool canWireFrame () { return true; } virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
@ -105,7 +105,7 @@ CTRTextureDetailMap2::CTRTextureDetailMap2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureDetailMap2::scanline_bilinear () void CTRTextureDetailMap2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -140,12 +140,11 @@ void CTRTextureDetailMap2::scanline_bilinear ()
xEnd = fill_convention_right( line.x[1] ); xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart; dx = xEnd - xStart;
if ( dx < 0 ) if ( dx < 0 )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -200,9 +199,9 @@ void CTRTextureDetailMap2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
if ( (0 == EdgeTestPass) & i ) break; if ( (0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -326,7 +325,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] ) if (F32_GREATER_0(scan.invDeltaY[1]) )
{ {
// calculate slopes for top edge // calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -394,9 +393,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -427,7 +427,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -461,10 +462,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] ) if (F32_GREATER_0(scan.invDeltaY[2]) )
{ {
// advance to middle point // advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] ) if(F32_GREATER_0(scan.invDeltaY[1]) )
{ {
temp[0] = b->Pos.y - a->Pos.y; // dy temp[0] = b->Pos.y - a->Pos.y; // dy
@ -521,7 +522,6 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -555,8 +555,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -587,7 +589,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -167,7 +167,7 @@ void CTRTextureGouraud2::fragmentShader ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -254,10 +254,10 @@ void CTRTextureGouraud2::fragmentShader ()
u32 dIndex = ( line.y & 3 ) << 2; u32 dIndex = ( line.y & 3 ) << 2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
//if test active only first pixel //if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -382,9 +382,9 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -551,9 +551,10 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -599,7 +600,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
@ -734,7 +735,6 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -761,7 +761,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
scan.c[1][1] += scan.slopeC[1][1] * subPixel; scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif #endif
#ifdef IPOL_C1 #ifdef IPOL_C2
scan.c[2][0] += scan.slopeC[2][0] * subPixel; scan.c[2][0] += scan.slopeC[2][0] * subPixel;
scan.c[2][1] += scan.slopeC[2][1] * subPixel; scan.c[2][1] += scan.slopeC[2][1] * subPixel;
#endif #endif
@ -782,9 +782,10 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -830,7 +831,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
//! constructor //! constructor
@ -104,7 +104,7 @@ CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureGouraudAdd2::scanline_bilinear () void CTRTextureGouraudAdd2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -144,7 +144,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -203,7 +203,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -280,9 +280,9 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
// find if the major edge is left or right aligned // find if the major edge is left or right aligned
f32 temp[4]; f32 temp[4];
@ -403,7 +403,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -434,7 +434,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -563,7 +563,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -594,7 +594,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -143,7 +143,7 @@ void CTRTextureGouraudAddNoZ2::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -200,7 +200,7 @@ void CTRTextureGouraudAddNoZ2::fragmentShader()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -275,9 +275,9 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -401,7 +401,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -432,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
fragmentShader(); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -526,7 +526,6 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -561,7 +560,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -592,7 +591,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
fragmentShader( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_; virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -115,7 +115,7 @@ void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& materi
/*! /*!
*/ */
void CTRTextureGouraudAlpha2::scanline_bilinear () void CTRTextureGouraudAlpha2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -155,7 +155,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -213,7 +213,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#endif #endif
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -337,9 +337,9 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -463,7 +463,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -494,7 +494,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -588,7 +588,6 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -623,7 +622,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -654,7 +653,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,20 +93,6 @@ public:
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_; virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_; virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1)
SBurningShaderMaterial Material;
virtual void setMaterial(const SBurningShaderMaterial &material)
{
Material = material;
}
virtual void setParam(u32 index, f32 value)
{
OnSetMaterial(Material);
}
#endif
private: private:
// fragment shader // fragment shader
@ -198,7 +184,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -268,7 +254,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
tFixPoint a3,r3, g3, b3; tFixPoint a3,r3, g3, b3;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -276,7 +262,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -418,7 +404,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -488,91 +474,91 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
tFixPoint a3, r3, g3, b3; tFixPoint a3, r3, g3, b3;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
#endif #endif
#ifdef CMP_W #ifdef CMP_W
if (line.w[0] >= z[i]) if (line.w[0] >= z[i])
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask[dIndex | (i) & 3]; const tFixPointu d = dithermask[dIndex | (i) & 3];
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]); inversew = fix_inverse32(line.w[0]);
#endif #endif
u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew), u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),
d + tofix(line.t[0][0].y, inversew) d + tofix(line.t[0][0].y, inversew)
); );
const tFixPoint alpha = (argb >> 24); const tFixPoint alpha = (argb >> 24);
if (alpha > AlphaRef) if (alpha > AlphaRef)
{ {
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
dst[i] = PixelBlend32(dst[i], argb, alpha); dst[i] = PixelBlend32(dst[i], argb, alpha);
} }
#else #else
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]); inversew = fix_inverse32(line.w[0]);
#endif #endif
getSample_texture(a0, r0, g0, b0, getSample_texture(a0, r0, g0, b0,
&IT[0], &IT[0],
tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].x, inversew),
tofix(line.t[0][0].y, inversew) tofix(line.t[0][0].y, inversew)
); );
if (a0 > AlphaRef) if (a0 > AlphaRef)
{ {
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew); vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew);
a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
r0 = imulFix(r0, r2); r0 = imulFix(r0, r2);
g0 = imulFix(g0, g2); g0 = imulFix(g0, g2);
b0 = imulFix(b0, b2); b0 = imulFix(b0, b2);
color_to_fix(r1, g1, b1, dst[i]); color_to_fix(r1, g1, b1, dst[i]);
fix_color_norm(a0); fix_color_norm(a0);
r2 = r1 + imulFix(a0, r0 - r1); r2 = r1 + imulFix(a0, r0 - r1);
g2 = g1 + imulFix(a0, g0 - g1); g2 = g1 + imulFix(a0, g0 - g1);
b2 = b1 + imulFix(a0, b0 - b1); b2 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix4_to_sample(a0, r2, g2, b2); dst[i] = fix4_to_sample(a0, r2, g2, b2);
#else #else
dst[i] = PixelBlend32(dst[i], dst[i] = PixelBlend32(dst[i],
fix_to_sample(r0, g0, b0), fix_to_sample(r0, g0, b0),
fixPointu_to_u32(a0) fixPointu_to_u32(a0)
); );
#endif
}
#endif #endif
} }
#endif
}
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ; line.z[0] += slopeZ;
@ -639,7 +625,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -708,15 +694,15 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
#ifdef IPOL_C1 #ifdef IPOL_C1
tFixPoint a3, r3, g3, b3; tFixPoint a3, r3, g3, b3;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) //if (line.z[0] < z[i])
#endif #endif
#ifdef CMP_W #ifdef CMP_W
// if (line.w[0] >= z[i]) // if (line.w[0] >= z[i])
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -827,9 +813,9 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -968,7 +954,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1004,6 +990,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline
scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -1112,7 +1100,6 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -1152,7 +1139,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1188,6 +1175,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline
scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -89,11 +89,16 @@ public:
//! draws an indexed triangle list //! draws an indexed triangle list
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_; virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private: private:
void scanline_bilinear ();
// fragment shader
typedef void (CTRTextureGouraudNoZ2::* tFragmentShader) ();
void fragment_bilinear();
void fragment_no_filter();
tFragmentShader fragmentShader;
}; };
//! constructor //! constructor
@ -103,13 +108,32 @@ CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRTextureGouraudNoZ2"); setDebugName("CTRTextureGouraudNoZ2");
#endif #endif
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;
} }
/*! /*!
*/ */
void CTRTextureGouraudNoZ2::scanline_bilinear ( ) void CTRTextureGouraudNoZ2::OnSetMaterial(const SBurningShaderMaterial& material)
{
if (material.org.TextureLayer[0].BilinearFilter ||
material.org.TextureLayer[0].TrilinearFilter ||
material.org.TextureLayer[0].AnisotropicFilter
)
{
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;
}
else
{
fragmentShader = &CTRTextureGouraudNoZ2::fragment_no_filter;
}
}
/*!
*/
void CTRTextureGouraudNoZ2::fragment_bilinear()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -149,7 +173,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -168,7 +192,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif #endif
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0]; subPixel = ((f32) xStart) - line.x[0];
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ * subPixel; line.z[0] += slopeZ * subPixel;
#endif #endif
@ -200,7 +224,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
tFixPoint ty0; tFixPoint ty0;
tFixPoint r0, g0, b0; tFixPoint r0, g0, b0;
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -208,7 +232,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
#endif #endif
scissor_test_x
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] ); inversew = fix_inverse32 ( line.w[0] );
@ -248,6 +272,146 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
} }
/*!
*/
void CTRTextureGouraudNoZ2::fragment_no_filter()
{
tVideoSample* dst;
#ifdef USE_ZBUFFER
fp24* z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if (dx < 0)
return;
// slopes
const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ((f32)xStart) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif
f32 inversew = FIX_POINT_F32_MUL;
tFixPoint tx0;
tFixPoint ty0;
//tFixPoint r0, g0, b0;
for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{
#ifdef CMP_Z
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if (line.w[0] >= z[i])
#endif
//scissor_test_x
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
tx0 = tofix(line.t[0][0].x,inversew);
ty0 = tofix(line.t[0][0].y,inversew);
//skybox
dst[i] = getTexel_plain(&IT[0], tx0, ty0);
//getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );
//dst[i] = fix_to_sample( r0, g0, b0 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{ {
// sort on height, y // sort on height, y
@ -258,10 +422,11 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
const f32 ca = c->Pos.y - a->Pos.y; const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -315,7 +480,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] ) if (F32_GREATER_0(scan.invDeltaY[1]) )
{ {
// calculate slopes for top edge // calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -385,7 +550,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -415,8 +580,11 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
line.t[1][scan.right] = scan.t[1][1]; line.t[1][scan.right] = scan.t[1][1];
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline
scissor_test_y
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -450,10 +618,10 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] ) if (F32_GREATER_0(scan.invDeltaY[2]) )
{ {
// advance to middle point // advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] ) if(F32_GREATER_0(scan.invDeltaY[1]) )
{ {
temp[0] = b->Pos.y - a->Pos.y; // dy temp[0] = b->Pos.y - a->Pos.y; // dy
@ -545,7 +713,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -576,7 +744,9 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline
scissor_test_y
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,7 +93,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -110,7 +110,7 @@ CTRTextureVertexAlpha2::CTRTextureVertexAlpha2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureVertexAlpha2::scanline_bilinear ( ) void CTRTextureVertexAlpha2::fragmentShader( )
{ {
tVideoSample *dst; tVideoSample *dst;
@ -150,7 +150,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -219,7 +219,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -332,9 +332,9 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -473,7 +473,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -509,7 +509,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -656,7 +656,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -692,7 +692,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -86,7 +86,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -103,7 +103,7 @@ CTRTextureLightMap2_Add::CTRTextureLightMap2_Add(CBurningVideoDriver* driver)
/*! /*!
*/ */
REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear () REALINLINE void CTRTextureLightMap2_Add::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -199,7 +199,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -274,9 +274,9 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -400,7 +400,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -431,7 +431,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -560,7 +560,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -591,7 +591,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -121,7 +121,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -193,7 +193,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
#endif #endif
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -255,9 +255,9 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -381,7 +381,7 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -542,7 +542,7 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];

@ -121,7 +121,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -254,9 +254,9 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -380,7 +380,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -411,7 +411,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2 (); interlace_scanline scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -541,7 +541,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -572,7 +572,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2 (); interlace_scanline scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,10 +93,10 @@ private:
void scanline_bilinear2_mag (); void scanline_bilinear2_mag ();
void scanline_bilinear2_min (); void scanline_bilinear2_min ();
#else #else
#define scanline_bilinear2_mag scanline_bilinear #define scanline_bilinear2_mag fragmentShader
#endif #endif
void scanline_bilinear (); void fragmentShader();
}; };
@ -130,7 +130,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
i = ( line.y * RenderTarget->getDimension().Width ) + xStart; i = ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -202,7 +202,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
#endif #endif
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -271,7 +271,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -334,7 +334,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -393,9 +393,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -519,7 +519,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -550,7 +550,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_min (); interlace_scanline scanline_bilinear2_min ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -680,7 +680,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -711,7 +711,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_min (); interlace_scanline scanline_bilinear2_min ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -769,9 +769,9 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
return; return;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
//if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) //if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
// return; // return;
@ -896,7 +896,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -927,7 +927,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_mag (); interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -1057,7 +1057,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1088,7 +1088,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_mag (); interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -86,7 +86,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -103,7 +103,7 @@ CTRGTextureLightMap2_M4::CTRGTextureLightMap2_M4(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGTextureLightMap2_M4::scanline_bilinear () void CTRGTextureLightMap2_M4::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -201,7 +201,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
tFixPoint r3, g3, b3; tFixPoint r3, g3, b3;
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X )
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -283,9 +283,9 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )
return; return;
@ -411,7 +411,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -442,7 +442,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -573,7 +573,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -604,7 +604,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -91,7 +91,7 @@ public:
virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; } virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const; void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const; void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;
@ -114,7 +114,7 @@ CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
*/ */
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const
{ {
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY; int pitch0 = RenderTarget->getDimension().Width << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
int pitch1 = RenderTarget->getDimension().Width << 2; int pitch1 = RenderTarget->getDimension().Width << 2;
#endif #endif
@ -138,7 +138,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
fp24 *z; fp24 *z;
#endif #endif
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY; int xInc0 = 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
int yInc0 = pitch0; int yInc0 = pitch0;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
@ -148,7 +148,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
if ( dx < 0 ) if ( dx < 0 )
{ {
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY); xInc0 = - ( 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY);
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
xInc1 = -4; xInc1 = -4;
#endif #endif
@ -173,7 +173,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
} }
SOFTWARE_DRIVER_2_CLIPCHECK_WIRE; SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;
dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) ); dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) ) );
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) ); z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
#endif #endif
@ -182,7 +182,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
m = dy << 1; m = dy << 1;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( (f32)dx ); const f32 invDeltaX = fill_step_x( (f32)dx );
#ifdef IPOL_Z #ifdef IPOL_Z
f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX; f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;
@ -283,7 +283,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
} }
void CTRTextureWire2::scanline_bilinear() void CTRTextureWire2::fragmentShader()
{ {
} }

@ -149,7 +149,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -206,7 +206,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
switch(MaterialType) { switch(MaterialType) {
default: default:
case EMT_REFLECTION_2_LAYER: case EMT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -263,7 +263,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
break; break;
case EMT_TRANSPARENT_REFLECTION_2_LAYER: case EMT_TRANSPARENT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -344,9 +344,9 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -470,7 +470,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -501,6 +501,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline
fragmentShader(); fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -630,7 +631,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -661,6 +662,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline
fragmentShader(); fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -12,29 +12,37 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
const tFixPointu IBurningShader::dithermask[] = const tFixPointu IBurningShader::dithermask[] =
{ {
0x00,0x80,0x20,0xa0, 0x00,0x80,0x20,0xa0,
0xc0,0x40,0xe0,0x60, 0xc0,0x40,0xe0,0x60,
0x30,0xb0,0x10,0x90, 0x30,0xb0,0x10,0x90,
0xf0,0x70,0xd0,0x50 0xf0,0x70,0xd0,0x50
}; };
void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver) void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("IBurningShader"); setDebugName("IBurningShader");
#endif #endif
if (((unsigned long long)&scan & 15) || ((unsigned long long)&line & 15))
{
os::Printer::log("BurningVideo Shader not 16 byte aligned", ELL_ERROR);
_IRR_DEBUG_BREAK_IF(1);
}
Interlaced.enable = 0;
Interlaced.bypass = 1;
Interlaced.nr = 0;
EdgeTestPass = edge_test_pass; EdgeTestPass = edge_test_pass;
EdgeTestPass_stack = edge_test_pass; EdgeTestPass_stack = edge_test_pass;
for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i ) for (u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i)
{ {
IT[i].Texture = 0; IT[i].Texture = 0;
} }
@ -44,12 +52,12 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
RenderTarget = 0; RenderTarget = 0;
ColorMask = COLOR_BRIGHT_WHITE; ColorMask = COLOR_BRIGHT_WHITE;
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer (); DepthBuffer = (CDepthBuffer*)driver->getDepthBuffer();
if ( DepthBuffer ) if (DepthBuffer)
DepthBuffer->grab(); DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer (); Stencil = (CStencilBuffer*)driver->getStencilBuffer();
if ( Stencil ) if (Stencil)
Stencil->grab(); Stencil->grab();
stencilOp[0] = StencilOp_KEEP; stencilOp[0] = StencilOp_KEEP;
@ -76,7 +84,7 @@ IBurningShader::IBurningShader(
const c8* pixelShaderProgram, const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName, const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget, E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram , const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName, const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget, E_GEOMETRY_SHADER_TYPE gsCompileTarget,
scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE inType,
@ -109,9 +117,9 @@ IBurningShader::~IBurningShader()
if (Stencil) if (Stencil)
Stencil->drop(); Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) for (u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i)
{ {
if ( IT[i].Texture ) if (IT[i].Texture)
IT[i].Texture->drop(); IT[i].Texture->drop();
} }
@ -121,12 +129,14 @@ IBurningShader::~IBurningShader()
} }
//! sets a render target //! sets a render target
void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort) void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced)
{ {
Interlaced = interlaced;
if (RenderTarget) if (RenderTarget)
RenderTarget->drop(); RenderTarget->drop();
RenderTarget = (video::CImage* ) surface; RenderTarget = (video::CImage*) surface;
if (RenderTarget) if (RenderTarget)
{ {
@ -138,16 +148,16 @@ void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s3
//! sets the Texture //! sets the Texture
void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor) void IBurningShader::setTextureParam(const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)
{ {
sInternalTexture *it = &IT[stage]; sInternalTexture* it = &IT[stage];
if ( it->Texture) if (it->Texture)
it->Texture->drop(); it->Texture->drop();
it->Texture = texture; it->Texture = texture;
if ( it->Texture) if (it->Texture)
{ {
it->Texture->grab(); it->Texture->grab();
@ -156,48 +166,52 @@ void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTextur
//only mipmap chain (means positive lodFactor) //only mipmap chain (means positive lodFactor)
u32 existing_level = it->Texture->getMipmapLevel(lodFactor); u32 existing_level = it->Texture->getMipmapLevel(lodFactor);
it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0); #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
it->data = (tVideoSample*)it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);
#else
it->data = (tVideoSample*)it->Texture->lock(ETLM_READ_ONLY, existing_level);
#endif
// prepare for optimal fixpoint // prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() ); it->pitchlog2 = s32_log2_s32(it->Texture->getPitch());
const core::dimension2d<u32> &dim = it->Texture->getSize(); const core::dimension2d<u32>& dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK; it->textureXMask = s32_to_fixPoint(dim.Width - 1) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK; it->textureYMask = s32_to_fixPoint(dim.Height - 1) & FIX_POINT_UNSIGNED_MASK;
} }
} }
//emulate a line with degenerate triangle and special shader mode (not perfect...) //emulate a line with degenerate triangle and special shader mode (not perfect...)
void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b) void IBurningShader::drawLine(const s4DVertex* a, const s4DVertex* b)
{ {
sVec2 d; sVec2 d;
d.x = b->Pos.x - a->Pos.x; d.x *= d.x; d.x = b->Pos.x - a->Pos.x; d.x *= d.x;
d.y = b->Pos.y - a->Pos.y; d.y *= d.y; d.y = b->Pos.y - a->Pos.y; d.y *= d.y;
//if ( d.x * d.y < 0.001f ) return; //if ( d.x * d.y < 0.001f ) return;
if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b); if (a->Pos.x > b->Pos.x) swapVertexPointer(&a, &b);
s4DVertex c = *a; s4DVertex c = *a;
const f32 w = (f32)RenderTarget->getDimension().Width-1; const f32 w = (f32)RenderTarget->getDimension().Width - 1;
const f32 h = (f32)RenderTarget->getDimension().Height-1; const f32 h = (f32)RenderTarget->getDimension().Height - 1;
if ( d.x < 2.f ) { c.Pos.x = b->Pos.x + 1.f + d.y; if ( c.Pos.x > w ) c.Pos.x = w; } if (d.x < 2.f) { c.Pos.x = b->Pos.x + 1.f + d.y; if (c.Pos.x > w) c.Pos.x = w; }
else c.Pos.x = b->Pos.x; else c.Pos.x = b->Pos.x;
if ( d.y < 2.f ) { c.Pos.y = b->Pos.y + 1.f; if ( c.Pos.y > h ) c.Pos.y = h; EdgeTestPass |= edge_test_first_line; } if (d.y < 2.f) { c.Pos.y = b->Pos.y + 1.f; if (c.Pos.y > h) c.Pos.y = h; EdgeTestPass |= edge_test_first_line; }
drawTriangle ( a,b,&c ); drawTriangle(a, b, &c);
EdgeTestPass &= ~edge_test_first_line; EdgeTestPass &= ~edge_test_first_line;
} }
void IBurningShader::drawPoint(const s4DVertex *a) void IBurningShader::drawPoint(const s4DVertex* a)
{ {
} }
void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) void IBurningShader::drawWireFrameTriangle(const s4DVertex* a, const s4DVertex* b, const s4DVertex* c)
{ {
if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c); if (EdgeTestPass & edge_test_pass) drawTriangle(a, b, c);
else if (EdgeTestPass & edge_test_point) else if (EdgeTestPass & edge_test_point)
{ {
drawPoint(a); drawPoint(a);
@ -256,7 +270,7 @@ void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMate
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
} }
s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name) s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags, const c8* name)
{ {
if (!name || !name[0]) if (!name || !name[0])
return -1; return -1;
@ -285,7 +299,7 @@ const char* tiny_itoa(s32 value, int base)
b[p] = '\0'; b[p] = '\0';
do { do {
b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base]; b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value % base];
value /= base; value /= base;
} while (value && p > 0); } while (value && p > 0);
@ -302,7 +316,7 @@ bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index,
BurningUniform add; BurningUniform add;
while ((u32)index >= UniformInfo.size()) while ((u32)index >= UniformInfo.size())
{ {
tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10)); tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(), 10));
add.type = flags; add.type = flags;
UniformInfo.push_back(add); UniformInfo.push_back(add);
} }
@ -340,7 +354,7 @@ void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister,
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH]; c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
tiny_strcpy(name, tiny_itoa(startRegister, 10)); tiny_strcpy(name, tiny_itoa(startRegister, 10));
setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount); setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM, name), data, constantAmount);
} }
void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)

@ -215,7 +215,6 @@ namespace video
}; };
class CBurningVideoDriver; class CBurningVideoDriver;
class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{ {
@ -247,7 +246,7 @@ namespace video
virtual ~IBurningShader(); virtual ~IBurningShader();
//! sets a render target //! sets a render target
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort); virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced);
//! sets the Texture //! sets the Texture
virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor); virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
@ -299,14 +298,38 @@ namespace video
virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_; virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_; virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
#endif
//used if no color interpolation is defined //used if no color interpolation is defined
void setPrimitiveColor(const video::SColor& color) void setPrimitiveColor(const video::SColor& color)
{ {
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8 PrimitiveColor = color_to_sample(color);
PrimitiveColor = color.color;
#else
PrimitiveColor = color.toA1R5G5B5();
#endif
} }
void setTLFlag(size_t in /*eTransformLightFlags*/) void setTLFlag(size_t in /*eTransformLightFlags*/)
{ {
@ -314,11 +337,7 @@ namespace video
} }
void setFog(SColor color_fog) void setFog(SColor color_fog)
{ {
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8 fog_color_sample = color_to_sample(color_fog);
fog_color_sample = color_fog.color;
#else
fog_color_sample = color_fog.toA1R5G5B5();
#endif
color_to_fix(fog_color, fog_color_sample); color_to_fix(fog_color, fog_color_sample);
} }
void setScissor(const AbsRectangle& scissor) void setScissor(const AbsRectangle& scissor)
@ -349,14 +368,15 @@ namespace video
static const tFixPointu dithermask[ 4 * 4]; static const tFixPointu dithermask[ 4 * 4];
//draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
int EdgeTestPass; //edge_test_flag size_t EdgeTestPass; //edge_test_flag
int EdgeTestPass_stack; size_t EdgeTestPass_stack;
interlaced_control Interlaced; // passed from driver
eBurningStencilOp stencilOp[4]; eBurningStencilOp stencilOp[4];
tFixPoint AlphaRef; tFixPoint AlphaRef;
int RenderPass_ShaderIsTransparent; int RenderPass_ShaderIsTransparent;
sScanConvertData scan; sScanConvertData ALIGN(16) scan;
sScanLineData line; sScanLineData line;
tVideoSample PrimitiveColor; //used if no color interpolation is defined tVideoSample PrimitiveColor; //used if no color interpolation is defined
@ -365,6 +385,17 @@ namespace video
tVideoSample fog_color_sample; tVideoSample fog_color_sample;
AbsRectangle Scissor; AbsRectangle Scissor;
inline tVideoSample color_to_sample(const video::SColor& color) const
{
//RenderTarget->getColorFormat()
#if SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT == ECF_A8R8G8B8
return color.color;
#else
return color.toA1R5G5B5();
#endif
}
}; };

@ -21,7 +21,7 @@ namespace video
virtual ~IDepthBuffer() {}; virtual ~IDepthBuffer() {};
//! clears the zbuffer //! clears the zbuffer
virtual void clear(f32 value) = 0; virtual void clear(f32 value, const interlaced_control interlaced) = 0;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0; virtual void setSize(const core::dimension2d<u32>& size) = 0;
@ -52,7 +52,7 @@ namespace video
virtual ~IStencilBuffer() {}; virtual ~IStencilBuffer() {};
//! clears the stencil buffer //! clears the stencil buffer
virtual void clear(u8 value) = 0; virtual void clear(u32 value, const interlaced_control interlaced) = 0;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0; virtual void setSize(const core::dimension2d<u32>& size) = 0;

@ -79,6 +79,13 @@ struct sVec2
#include "irrpack.h" #include "irrpack.h"
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texutre Coordinates.
// Start address is not 4 byte aligned
struct sVec2Pack
{
f32 x, y;
};
//! sVec3Pack used in BurningShader, packed direction //! sVec3Pack used in BurningShader, packed direction
struct sVec3Pack struct sVec3Pack
{ {
@ -529,7 +536,7 @@ typedef s4DVertex s4DVertexPair;
struct SAligned4DVertex struct SAligned4DVertex
{ {
SAligned4DVertex() SAligned4DVertex()
:data(0),mem(0), ElementSize(0) {} :data(0),ElementSize(0),mem(0) {}
virtual ~SAligned4DVertex () virtual ~SAligned4DVertex ()
{ {
@ -553,8 +560,11 @@ struct SAligned4DVertex
} }
s4DVertex* data; //align to 16 byte s4DVertex* data; //align to 16 byte
u8* mem;
size_t ElementSize; size_t ElementSize;
private:
u8* mem;
}; };
//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2) //#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)
@ -732,7 +742,7 @@ struct sScanConvertData
{ {
u32 left; // major edge left/right u32 left; // major edge left/right
u32 right; // !left u32 right; // !left
u32 _unused_pack[2]; u8 _unused_pack[8];
f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle
@ -767,7 +777,7 @@ struct sScanConvertData
struct sScanLineData struct sScanLineData
{ {
s32 y; // y position of scanline s32 y; // y position of scanline
u32 _unused_pack[1]; u8 _unused_pack[4];
f32 x[2]; // x start, x end of scanline f32 x[2]; // x start, x end of scanline
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) #if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
@ -776,7 +786,8 @@ struct sScanLineData
f32 z[2]; // z start, z end of scanline f32 z[2]; // z start, z end of scanline
#endif #endif
u32 _unused_pack_1[2]; s32 x_edgetest; // slope x
u8 _unused_pack_1[4];
#if BURNING_MATERIAL_MAX_COLORS > 0 #if BURNING_MATERIAL_MAX_COLORS > 0
sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline

@ -10,140 +10,167 @@
// Generic Render Flags for burning's video rasterizer // Generic Render Flags for burning's video rasterizer
// defined now in irrlicht compile config // defined now in irrlicht compile config
#if defined(PATCH_SUPERTUX_8_0_1) #if 1 && defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#undef BURNINGVIDEO_RENDERER_BEAUTIFUL #undef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL
#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL #define SOFTWARE_DRIVER_2_SUBTEXEL
#define SOFTWARE_DRIVER_2_BILINEAR #define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING #define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0 #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0x100000
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_2D_AS_3D #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
//! Set Flags for Windows Mobile //! Set Flags for Windows Mobile
#ifdef BURNINGVIDEO_RENDERER_CE #ifdef BURNINGVIDEO_RENDERER_CE
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL #define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR //#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64 #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
//#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_FAST #ifdef BURNINGVIDEO_RENDERER_FAST
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL #define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR //#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_32BIT #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256 #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST #ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST
#define BURNINGVIDEO_RENDERER_FAST #define BURNINGVIDEO_RENDERER_FAST
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
//#define SOFTWARE_DRIVER_2_SUBTEXEL //#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR //#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_32BIT //#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_16BIT
//#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
//#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128 //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
//#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
// Derivate flags
// texture format
#ifdef SOFTWARE_DRIVER_2_32BIT
#define BURNINGSHADER_COLOR_FORMAT ECF_A8R8G8B8
#else
#define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5
#endif
// mip mapping - precalculated texture filter
#if defined ( SOFTWARE_DRIVER_2_MIPMAPPING )
#if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#elif defined ( BURNINGVIDEO_RENDERER_CE )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#endif
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#endif
#ifndef REALINLINE #ifndef REALINLINE
#ifdef _MSC_VER #ifdef _MSC_VER
#define REALINLINE __forceinline #define REALINLINE __forceinline
#else #else
#define REALINLINE inline #define REALINLINE inline
#endif #endif
#endif #endif
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
//Control Scanline output
#define SOFTWARE_DRIVER_2_STEP_X 1
#define SOFTWARE_DRIVER_2_STEP_Y 1
// null check necessary (burningvideo only) // null check necessary (burningvideo only)
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f) #define fill_step_y(y) ((y) != 0.f ? (float)1.f / (y):0.f)
static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; } static inline float fill_step_x(float x) { return x != 0.f ? (float)SOFTWARE_DRIVER_2_STEP_X / x : 0.f; }
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
#define interlace_control_bit 1
#define interlace_control_mask ((1<<interlace_control_bit)-1)
struct interlaced_control
{
unsigned enable : 1;
unsigned bypass : 1;
unsigned nr : interlace_control_bit;
};
struct interlace_scanline_data { unsigned int y; };
static inline interlaced_control interlace_disabled()
{
interlaced_control v;
v.enable = 0;
v.bypass = 1;
v.nr = 0;
return v;
}
#if defined(SOFTWARE_DRIVER_2_INTERLACED)
#define interlace_scanline if ( Interlaced.bypass | ((line.y & interlace_control_mask) == Interlaced.nr) )
#define interlace_scanline_enabled if ( (line.y & interlace_control_mask) == Interlaced.nr )
//#define interlace_scanline if ( Interlaced.disabled | (((line.y >> (interlace_control_bit-1) ) & 1) == (Interlaced.nr & 1)) )
//#define interlace_scanline
#else
#define interlace_scanline
#define interlace_scanline_enabled
#endif
#define scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1)))
#define scissor_test_x if ((~TL_Flag & TL_SCISSOR) || ((i+xStart >= Scissor.x0) & (i+xStart <= Scissor.x1)))
#define fill_convention_left(x) (s32) ceilf(x) #define fill_convention_left(x) (s32) ceilf(x)
#define fill_convention_right(x) ((s32) ceilf(x))-1 #define fill_convention_right(x) ((s32) ceilf(x))-1
#define fill_convention_none(x) (s32) (x) #define fill_convention_none(x) (s32) (x)
#define fill_convention_edge(x) (s32) floorf(fabsf(x)+0.f)
//#define fill_convention_left(x) 65536 - int(65536.0f - x) //#define fill_convention_left(x) 65536 - int(65536.0f - x)
//#define fill_convention_right(x) 65535 - int(65536.0f - x) //#define fill_convention_right(x) 65535 - int(65536.0f - x)
@ -157,7 +184,7 @@ static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f;
inline float reciprocal_zero_no(const float x) inline float reciprocal_zero_no(const float x)
{ {
if (x*x <= 0.00001f) __debugbreak(); if (x * x <= 0.00001f) __debugbreak();
return 1.f / x; return 1.f / x;
} }
#else #else
@ -183,49 +210,49 @@ enum edge_test_flag
#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2 #define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2
//! from 1 bit to 5 bit //! from 1 bit to 5 bit
#ifdef SOFTWARE_DRIVER_2_32BIT #if defined(SOFTWARE_DRIVER_2_32BIT)
#define fix_alpha_color_max(x) #define fix_alpha_color_max(x)
#else #else
#define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1 #define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1
#endif #endif
// Check windows // Check windows
#if _WIN32 || _WIN64 #if _WIN32 || _WIN64
#if _WIN64 #if _WIN64
#define ENV64BIT #define ENV64BIT
#else #else
#define ENV32BIT #define ENV32BIT
#endif #endif
#endif #endif
// Check GCC // Check GCC
#if __GNUC__ #if __GNUC__
#if __x86_64__ || __ppc64__ #if __x86_64__ || __ppc64__
#define ENV64BIT #define ENV64BIT
#else #else
#define ENV32BIT #define ENV32BIT
#endif #endif
#endif #endif
#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL) #if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)
typedef float ipoltype; typedef float ipoltype;
#else #else
typedef float ipoltype; typedef float ipoltype;
#endif #endif
#define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0) #define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0)
#define ipol_greater_0(n) ((n) > (ipoltype)0.0) #define ipol_greater_0(n) ((n) > (ipoltype)0.0)
#if (_MSC_VER > 1700 ) #if (_MSC_VER > 1700 )
#define burning_restrict __restrict #define burning_restrict __restrict
#else #else
#define burning_restrict #define burning_restrict
#endif #endif
/* /*
if (condition) state |= mask; else state &= ~mask; if (condition) state |= mask; else state &= ~mask;
*/ */
static inline void burning_setbit(size_t &state, int condition, size_t mask) static inline void burning_setbit(size_t& state, int condition, size_t mask)
{ {
if (condition) state |= mask; if (condition) state |= mask;
else state &= ~mask; else state &= ~mask;
@ -234,7 +261,7 @@ static inline void burning_setbit(size_t &state, int condition, size_t mask)
/* /*
if (condition) state |= m; else state &= ~m; if (condition) state |= m; else state &= ~m;
*/ */
REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask) REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask)
{ {
// 0, or any positive to mask // 0, or any positive to mask
//s32 conmask = -condition >> 31; //s32 conmask = -condition >> 31;
@ -246,44 +273,46 @@ REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsig
#define burning_create(s) burning_create_indirect(s) #define burning_create(s) burning_create_indirect(s)
#if defined(PATCH_SUPERTUX_8_0_1) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#define getData lock
#define snprintf_irr sprintf_s #define snprintf_irr sprintf_s
#define EVDF_DEPTH_CLAMP 43
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define E_CUBE_SURFACE int
#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR #define ECFN_DISABLED 0
#define BURNING_MATERIAL_MAX_COLORS 2
#else
#define BURNING_MATERIAL_MAX_COLORS 1
#endif
#else
#define BURNING_MATERIAL_MAX_COLORS 0
#endif
#ifndef _IRR_OVERRIDE_
#define _IRR_OVERRIDE_ /**/
#endif
#define fix_to_color fix_to_sample
#define fix4_to_color fix4_to_sample
#define vec4_to_fix getSample_color
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
namespace irr { namespace irr {
namespace video {
REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize) //! Enum for the flags of clear buffer
{ enum E_CLEAR_BUFFER_FLAG
size_t c = bytesize >> 2;
do
{ {
((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1]; ECBF_NONE = 0,
} while (--c); ECBF_COLOR = 1,
ECBF_DEPTH = 2,
ECBF_STENCIL = 4,
ECBF_ALL = ECBF_COLOR | ECBF_DEPTH | ECBF_STENCIL
};
//! For SMaterial.ZWriteEnable
enum E_ZWRITE
{
EZW_OFF = 0,
EZW_AUTO,
EZW_ON
};
} }
}
#endif // PATCH_SUPERTUX_8_0_1_with_1_9_0
} // namespace irr //! Size of a static C-style array.
#endif // #if defined(PATCH_SUPERTUX_8_0_1) #define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))
//! Compiler Align
#if defined(_MSC_VER)
#define ALIGN(x) __declspec(align(x))
#elif defined(__GNUC__)
#define ALIGN(x) __attribute__ ((aligned(x)))
#else
#define ALIGN(x)
#endif
#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ #endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__

@ -22,7 +22,7 @@ namespace irr
// supporting different packed pixel needs many defines... // supporting different packed pixel needs many defines...
#ifdef SOFTWARE_DRIVER_2_32BIT #if defined(SOFTWARE_DRIVER_2_32BIT)
typedef u32 tVideoSample; typedef u32 tVideoSample;
typedef u32 tStencilSample; typedef u32 tStencilSample;
@ -40,8 +40,8 @@ namespace irr
#define COLOR_MAX_LOG2 8 #define COLOR_MAX_LOG2 8
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF #define COLOR_BRIGHT_WHITE 0xFFFFFFFF
#define VIDEO_SAMPLE_GRANULARITY (unsigned)2 #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)2
#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)2
#else #else
typedef u16 tVideoSample; typedef u16 tVideoSample;
typedef u8 tStencilSample; typedef u8 tStencilSample;
@ -59,7 +59,8 @@ namespace irr
#define COLOR_MAX 0x1F #define COLOR_MAX 0x1F
#define COLOR_MAX_LOG2 5 #define COLOR_MAX_LOG2 5
#define COLOR_BRIGHT_WHITE 0xFFFF #define COLOR_BRIGHT_WHITE 0xFFFF
#define VIDEO_SAMPLE_GRANULARITY (unsigned)1 #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)1
#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)1
#endif #endif
@ -140,6 +141,19 @@ inline void memset16(void * dest, const u16 value, size_t bytesize)
} }
} }
//! memset interleaved
inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 height,const interlaced_control Interlaced)
{
if (Interlaced.bypass) return memset32(dest, value, pitch * height);
u8* dst = (u8*)dest;
interlace_scanline_data line;
for (line.y = 0; line.y < height; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{
interlace_scanline_enabled memset32(dst, value, pitch);
dst += pitch;
}
}
// byte-align structures // byte-align structures
#include "irrpack.h" #include "irrpack.h"
@ -577,7 +591,7 @@ REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
*/ */
REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)
{ {
#ifdef SOFTWARE_DRIVER_2_32BIT #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4); return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);
#else #else
return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5); return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);
@ -598,7 +612,7 @@ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y) REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
{ {
#ifdef SOFTWARE_DRIVER_2_32BIT #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2); tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);
#else #else
tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3); tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);
@ -608,17 +622,6 @@ REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
} }
#if 0
#define imulFix_tex1(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4))
#define imulFix_tex2(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3))
#ifdef SOFTWARE_DRIVER_2_32BIT
#define imulFix_tex4(x,y) ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 )
#else
#define imulFix_tex4(x,y) ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) )
#endif
#endif
/*! /*!
clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX) clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)
*/ */
@ -831,7 +834,7 @@ static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFi
size_t ofs; size_t ofs;
ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
return *((tVideoSample*)( (u8*) t->data + ofs )); return *((tVideoSample*)( (u8*) t->data + ofs ));
@ -845,7 +848,7 @@ inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
size_t ofs; size_t ofs;
ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -865,7 +868,7 @@ inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
size_t ofs; size_t ofs;
ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -886,7 +889,7 @@ static REALINLINE void getTexel_fix ( tFixPoint &a,
size_t ofs; size_t ofs;
ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -913,7 +916,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -937,8 +940,8 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
//wraps positive (ignoring negative) //wraps positive (ignoring negative)
o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2))); t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));
r00 = (t00 & MASK_R) >> SHIFT_R; r00 = (t00 & MASK_R) >> SHIFT_R;
@ -1001,7 +1004,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
//nearest neighbor //nearest neighbor
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
tVideoSample t00; tVideoSample t00;
t00 = *((tVideoSample*)((u8*)tex->data + ofs)); t00 = *((tVideoSample*)((u8*)tex->data + ofs));
@ -1029,8 +1032,8 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
size_t o0, o1, o2, o3; size_t o0, o1, o2, o3;
o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3))); t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
@ -1072,8 +1075,8 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &
o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
a00 = (t00 & MASK_A) >> SHIFT_A; a00 = (t00 & MASK_A) >> SHIFT_A;
@ -1144,7 +1147,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
{ {
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
@ -1160,7 +1163,7 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &
{ {
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
@ -1233,8 +1236,6 @@ static inline int tiny_isequal(const char *s1, const char *s2, size_t n)
} }
#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0 #define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0
//! Size of a static C-style array.
#define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))
} // end namespace irr } // end namespace irr

@ -40,7 +40,7 @@ void burning_shader_class::burning_shader_fragment()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -96,9 +96,9 @@ void burning_shader_class::burning_shader_fragment()
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i+= SOFTWARE_DRIVER_2_STEP_X)
{ {
if ((0 == EdgeTestPass) & i) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])

@ -139,8 +139,10 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y) for (line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -171,6 +173,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;
@ -265,7 +268,6 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
yEnd = fill_convention_right(c->Pos.y); yEnd = fill_convention_right(c->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ((f32)yStart) - b->Pos.y; subPixel = ((f32)yStart) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -299,8 +301,10 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y) for (line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -331,6 +335,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;

@ -1,48 +1,47 @@
Libpng 1.6.23 - June 9, 2016 libpng 1.6.37 - April 14, 2019
==============================
This is a public release of libpng, intended for use in production codes. This is a public release of libpng, intended for use in production code.
Files available for download:
Source files with LF line endings (for Unix/Linux) and with a Files available for download
"configure" script ----------------------------
libpng-1.6.23.tar.xz (LZMA-compressed, recommended) Source files with LF line endings (for Unix/Linux):
libpng-1.6.23.tar.gz
Source files with CRLF line endings (for Windows), without the * libpng-1.6.37.tar.xz (LZMA-compressed, recommended)
"configure" script * libpng-1.6.37.tar.gz
lpng1623.7z (LZMA-compressed, recommended) Source files with CRLF line endings (for Windows):
lpng1623.zip
* lp1637.7z (LZMA-compressed, recommended)
* lp1637.zip
Other information: Other information:
libpng-1.6.23-README.txt * README.md
libpng-1.6.23-LICENSE.txt * LICENSE.md
libpng-1.6.23-*.asc (armored detached GPG signatures) * AUTHORS.md
* TRADEMARK.md
Changes since the last public release (1.6.22):
Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying). Changes since the previous public release (version 1.6.36)
Fixed the progressive reader to handle empty first IDAT chunk properly ----------------------------------------------------------
(patch by Timothy Nikkel). This bug was introduced in libpng-1.6.0 and
only affected the libpng16 branch.
Added tests in pngvalid.c to check zero-length IDAT chunks in various
positions. Fixed the sequential reader to handle these more robustly
(John Bowler).
Corrected progressive read input buffer in pngvalid.c. The previous version
the code invariably passed just one byte at a time to libpng. The intent
was to pass a random number of bytes in the range 0..511.
Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch.
Added missing ")" in pngerror.c (Matt Sarrett).
Fixed undefined behavior in png_push_save_buffer(). Do not call
memcpy() with a null source, even if count is zero (Leon Scroggins III).
Fixed bad link to RFC2083 in png.5 (Nikola Forro).
(subscription required; visit * Fixed a use-after-free vulnerability (CVE-2019-7317) in png_image_free.
* Fixed a memory leak in the ARM NEON implementation of png_do_expand_palette.
* Fixed a memory leak in pngtest.c.
* Fixed two vulnerabilities (CVE-2018-14048, CVE-2018-14550) in
contrib/pngminus; refactor.
* Changed the license of contrib/pngminus to MIT; refresh makefile and docs.
(Contributed by Willem van Schaik)
* Fixed a typo in the libpng license v2.
(Contributed by Miguel Ojeda)
* Added makefiles for AddressSanitizer-enabled builds.
* Cleaned up various makefiles.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement https://lists.sourceforge.net/lists/listinfo/png-mng-implement
to subscribe) to subscribe.
or to glennrp at users.sourceforge.net
Glenn R-P

@ -0,0 +1,45 @@
PNG REFERENCE LIBRARY AUTHORS
=============================
This is the list of PNG Reference Library ("libpng") Contributing
Authors, for copyright and licensing purposes.
* Andreas Dilger
* Cosmin Truta
* Dave Martindale
* Eric S. Raymond
* Gilles Vollant
* Glenn Randers-Pehrson
* Greg Roelofs
* Guy Eric Schalnat
* James Yu
* John Bowler
* Kevin Bracey
* Magnus Holmgren
* Mandar Sahastrabuddhe
* Mans Rullgard
* Matt Sarett
* Mike Klein
* Paul Schmidt
* Sam Bushell
* Samuel Williams
* Simon-Pierre Cadieux
* Tim Wegner
* Tom Lane
* Tom Tanner
* Vadim Barkov
* Willem van Schaik
* Zhijie Liang
* Arm Holdings
- Richard Townsend
* Google Inc.
- Matt Sarett
- Mike Klein
The build projects, the build scripts, the test scripts, and other
files in the "projects", "scripts" and "tests" directories, have other
copyright owners, but are released under the libpng license.
Some files in the "contrib" directory, and some tools-generated files
that are distributed with libpng, have other copyright owners, and are
released under other open source licenses.

@ -1,4 +1,3 @@
#if 0
CHANGES - changes for libpng CHANGES - changes for libpng
version 0.1 [March 29, 1995] version 0.1 [March 29, 1995]
@ -593,7 +592,7 @@ Version 1.0.5e [November 30, 1999]
with trailing compressed parts easier in the future, and added new functions with trailing compressed parts easier in the future, and added new functions
png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
NOTE: Applications that write text chunks MUST define png_text->lang NOTE: Applications that write text chunks MUST define png_text->lang
before calling png_set_text(). It must be set to NULL if you want to before calling png_set_text(). It must be set to NULL if you want to
write tEXt or zTXt chunks. If you want your application to be able to write tEXt or zTXt chunks. If you want your application to be able to
run with older versions of libpng, use run with older versions of libpng, use
@ -833,7 +832,7 @@ Version 1.0.7beta11 [May 7, 2000]
Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
which are no longer used. which are no longer used.
Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED
is defined. is defined.
Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
overrun when old applications fill the info_ptr->text structure directly. overrun when old applications fill the info_ptr->text structure directly.
@ -1454,7 +1453,7 @@ Version 1.2.6beta4 [July 28, 2004]
sequential read support. sequential read support.
Added some "#if PNG_WRITE_SUPPORTED" blocks. Added some "#if PNG_WRITE_SUPPORTED" blocks.
Added #ifdef to remove some redundancy in png_malloc_default(). Added #ifdef to remove some redundancy in png_malloc_default().
Use png_malloc instead of png_zalloc to allocate the pallete. Use png_malloc instead of png_zalloc to allocate the palette.
Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004]
Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS(). Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS().
@ -3259,7 +3258,7 @@ Version 1.5.2beta01 [February 13, 2011]
Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the
old VisualC++ preprocessor. old VisualC++ preprocessor.
Turned on interlace handling in png_read_png(). Turned on interlace handling in png_read_png().
Fixed gcc pendantic warnings. Fixed gcc pedantic warnings.
Handle longjmp in Cygwin. Handle longjmp in Cygwin.
Fixed png_get_current_row_number() in the interlaced case. Fixed png_get_current_row_number() in the interlaced case.
Cleaned up ALPHA flags and transformations. Cleaned up ALPHA flags and transformations.
@ -3359,7 +3358,7 @@ Version 1.5.3beta05 [May 6, 2011]
Pass "" instead of '\0' to png_default_error() in png_err(). This mistake Pass "" instead of '\0' to png_default_error() in png_err(). This mistake
was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691.
Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte
optimization configureable. optimization configurable.
IDAT compression failed if preceded by a compressed text chunk (bug IDAT compression failed if preceded by a compressed text chunk (bug
introduced in libpng-1.5.3beta01-02). This was because the attempt to introduced in libpng-1.5.3beta01-02). This was because the attempt to
reset the zlib stream in png_write_IDAT happened after the first IDAT reset the zlib stream in png_write_IDAT happened after the first IDAT
@ -3643,7 +3642,7 @@ Version 1.5.6beta05 [October 12, 2011]
Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01.
Version 1.5.6beta06 [October 17, 2011] Version 1.5.6beta06 [October 17, 2011]
Removed two redundant tests for unitialized row. Removed two redundant tests for uninitialized row.
Fixed a relatively harmless memory overwrite in compressed text writing Fixed a relatively harmless memory overwrite in compressed text writing
with a 1 byte zlib buffer. with a 1 byte zlib buffer.
Add ability to call png_read_update_info multiple times to pngvalid.c. Add ability to call png_read_update_info multiple times to pngvalid.c.
@ -3689,7 +3688,7 @@ Version 1.5.7beta01 [November 4, 2011]
crash. The pngmem.c implementation of png_malloc() included a cast crash. The pngmem.c implementation of png_malloc() included a cast
to png_size_t which would fail on large allocations on 16-bit systems. to png_size_t which would fail on large allocations on 16-bit systems.
Fix for the preprocessor of the Intel C compiler. The preprocessor Fix for the preprocessor of the Intel C compiler. The preprocessor
splits adjacent @ signs with a space; this changes the concatentation splits adjacent @ signs with a space; this changes the concatenation
token from @-@-@ to PNG_JOIN; that should work with all compiler token from @-@-@ to PNG_JOIN; that should work with all compiler
preprocessors. preprocessors.
Paeth filter speed improvements from work by Siarhei Siamashka. This Paeth filter speed improvements from work by Siarhei Siamashka. This
@ -3735,7 +3734,7 @@ Version 1.5.7beta03 [November 17, 2011]
gray (on palette) itself. gray (on palette) itself.
Fixes for C++ compilation using g++ When libpng source is compiled Fixes for C++ compilation using g++ When libpng source is compiled
using g++. The compiler imposes C++ rules on the C source; thus it using g++. The compiler imposes C++ rules on the C source; thus it
is desireable to make the source work with either C or C++ rules is desirable to make the source work with either C or C++ rules
without throwing away useful error information. This change adds without throwing away useful error information. This change adds
png_voidcast to allow C semantic (void*) cases or the corresponding png_voidcast to allow C semantic (void*) cases or the corresponding
C++ static_cast operation, as appropriate. C++ static_cast operation, as appropriate.
@ -4061,7 +4060,7 @@ Version 1.6.0beta17 [March 10, 2012]
possible to call png_inflate() incrementally. A warning is no longer possible to call png_inflate() incrementally. A warning is no longer
issued if the language tag or translated keyword in the iTXt chunk issued if the language tag or translated keyword in the iTXt chunk
has zero length. has zero length.
If benign errors are disabled use maximum window on ancilliary inflate. If benign errors are disabled use maximum window on ancillary inflate.
This works round a bug introduced in 1.5.4 where compressed ancillary This works round a bug introduced in 1.5.4 where compressed ancillary
chunks could end up with a too-small windowBits value in the deflate chunks could end up with a too-small windowBits value in the deflate
header. header.
@ -4176,7 +4175,7 @@ Version 1.6.0beta27 [August 11, 2012]
declared even though the functions are never actually defined. This declared even though the functions are never actually defined. This
change provides a dummy definition so that the declarations work, yet any change provides a dummy definition so that the declarations work, yet any
implementation will fail to compile because of an incomplete type. implementation will fail to compile because of an incomplete type.
Re-eliminated the use of strcpy() in pngtest.c. An unncessary use of Re-eliminated the use of strcpy() in pngtest.c. An unnecessary use of
strcpy() was accidentally re-introduced in libpng16; this change replaces strcpy() was accidentally re-introduced in libpng16; this change replaces
it with strncpy(). it with strncpy().
Eliminated use of png_sizeof(); use sizeof() instead. Eliminated use of png_sizeof(); use sizeof() instead.
@ -4309,7 +4308,7 @@ Version 1.6.0beta31 [November 1, 2012]
resulting in VS2010 having to update the files. resulting in VS2010 having to update the files.
Removed non-working ICC profile support code that was mostly added to Removed non-working ICC profile support code that was mostly added to
libpng-1.6.0beta29 and beta30. There was too much code for too little libpng-1.6.0beta29 and beta30. There was too much code for too little
gain; implementing full ICC color correction may be desireable but is left gain; implementing full ICC color correction may be desirable but is left
up to applications. up to applications.
Version 1.6.0beta32 [November 25, 2012] Version 1.6.0beta32 [November 25, 2012]
@ -4592,7 +4591,7 @@ Version 1.6.3beta07 [June 8, 2013]
the optimizations ('check' vs 'api') are exposed in the public header files the optimizations ('check' vs 'api') are exposed in the public header files
except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the
decision about whether or not to use the optimizations. decision about whether or not to use the optimizations.
Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage. Protect symbol prefixing against CC/CPPFLAGS/CFLAGS usage.
Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test
on __ARM_NEON__ from configure time to compile time. This breaks symbol on __ARM_NEON__ from configure time to compile time. This breaks symbol
prefixing because the definition of the special png_init_filter_functions prefixing because the definition of the special png_init_filter_functions
@ -5596,11 +5595,515 @@ Version 1.6.23rc02 [June 4, 2016]
Version 1.6.23 [June 9, 2016] Version 1.6.23 [June 9, 2016]
Fixed bad link to RFC2083 in png.5 (Nikola Forro). Fixed bad link to RFC2083 in png.5 (Nikola Forro).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Version 1.6.24beta01 [June 11, 2016]
(subscription required; visit Avoid potential overflow of the PNG_IMAGE_SIZE macro. This macro
https://lists.sourceforge.net/lists/listinfo/png-mng-implement is not used within libpng, but is used in some of the examples.
to subscribe)
or to glennrp at users.sourceforge.net
Glenn R-P Version 1.6.24beta02 [June 23, 2016]
#endif Correct filter heuristic overflow handling. This was broken when the
write filter code was moved out-of-line; if there is a single filter and
the heuristic sum overflows the calculation of the filtered line is not
completed. In versions prior to 1.6 the code was duplicated in-line
and the check not performed, so the filter operation completed; however,
in the multi-filter case where the sum is performed the 'none' filter would
be selected if all the sums overflowed, even if it wasn't in the filter
list. The fix to the first problem is simply to provide PNG_SIZE_MAX as
the current lmins sum value; this means the sum can never exceed it and
overflows silently. A reasonable compiler that does choose to inline
the code will simply eliminate the sum check.
The fix to the second problem is to use high precision arithmetic (this is
implemented in 1.7), however a simple safe fix here is to chose the lowest
numbered filter in the list from png_set_filter (this only works if the
first problem is also fixed) (John Bowler).
Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois).
Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application
as a result of the application using an increased 'row_stride'; previously
png_image_finish_read only checked for overflow on the base calculation of
components. (I.e. it checked for overflow of a 32-bit number on the total
number of pixel components in the output format, not the possibly padded row
length and not the number of bytes, which for linear formats is twice the
number of components.)
MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned)
MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless
the conversion is explicitly invoked by a cast.
Put the SKIP definition in the correct place. It needs to come after the
png.h include (see all the other .c files in contrib/libtests) because it
depends on PNG_LIBPNG_VER.
Removed the three compile warning options from the individual project
files into the zlib.props globals. It increases the warning level from 4
to All and adds a list of the warnings that need to be turned off. This is
semi-documentary; the intent is to tell libpng users which warnings have
been examined and judged non-fixable at present. The warning about
structure padding is fixable, but it would be a significant change (moving
structure members around).
Version 1.6.24beta03 [July 4, 2016]
Optimized absolute value calculation in filter selection, similar to
code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to
use this.
Added pngcp to the build together with a pngcp.dfa configuration test.
Added high resolution timing to pngcp.
Added "Common linking failures" section to INSTALL.
Relocated misplaced #endif in png.c sRGB profile checking.
Fixed two Coverity issues in pngcp.c.
Version 1.6.24beta04 [July 8, 2016]
Avoid filter-selection heuristic sum calculations in cases where only one
filter is a candidate for selection. This trades off code size (added
private png_setup_*_row_only() functions) for speed.
Version 1.6.24beta05 [July 13, 2016]
Fixed some indentation to comply with our coding style.
Added contrib/tools/reindent.
Version 1.6.24beta06 [July 18, 2016]
Fixed more indentation to comply with our coding style.
Eliminated unnecessary tests of boolean png_isaligned() vs 0.
Version 1.6.24rc01 [July 25, 2016]
No changes.
Version 1.6.24rc02 [August 1, 2016]
Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch
Conditionally compile png_decompress_chunk().
Version 1.6.24rc03 [August 2, 2016]
Conditionally compile ARM_NEON headers in pngpriv.h
Updated contrib/intel/intel_sse.patch
Version 1.6.24[August 4, 2016]
No changes.
Version 1.6.25beta01 [August 12, 2016]
Reject oversized iCCP profile immediately.
Cleaned up PNG_DEBUG compile of pngtest.c.
Conditionally compile png_inflate().
Version 1.6.25beta02 [August 18, 2016]
Don't install pngcp; it conflicts with pngcp in the pngtools package.
Minor editing of INSTALL, (whitespace, added copyright line)
Version 1.6.25rc01 [August 24, 2016]
No changes.
Version 1.6.25rc02 [August 29, 2016]
Added MIPS support (Mandar Sahastrabuddhe <Mandar.Sahastrabuddhe@imgtec.com>).
Only the UP filter is currently implemented.
Version 1.6.25rc03 [August 29, 2016]
Rebased contrib/intel/intel_sse.patch after the MIPS implementation.
Version 1.6.25rc04 [August 30, 2016]
Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe).
Version 1.6.25rc05 [August 30, 2016]
Rebased contrib/intel/intel_sse.patch after the MIPS implementation update..
Version 1.6.25 [September 1, 2016]
No changes.
Version 1.6.26beta01 [September 26, 2016]
Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo,
bugfix by John Bowler).
Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL
has allocated memory that libpng needs to free.
Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c
Issue a png_benign_error instead of a png_error on ADLER32 mismatch
while decoding compressed data chunks.
Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and
pngrutil.c.
If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE,
ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs.
Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error().
Add tests/badcrc.png and tests/badadler.png to tests/pngtest.
Merged pngtest.c with libpng-1.7.0beta84/pngtest.c
Version 1.6.26beta02 [October 1, 2016]
Updated the documentation about CRC and ADLER32 handling.
Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c,
pngwrite.c, pngunknown.c, and pngvalid.c.
Quieted 58 (out of 144) -Wconversion compiler warnings by changing
flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes
in png.c, pngread.c, and pngwutil.c.
Version 1.6.26beta03 [October 2, 2016]
Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs.
Quieted the 86 remaining -Wconversion compiler warnings by
revising the png_isaligned() macro and trivial changes in png.c,
pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c,
pngwtran.c, pngwrite.c, and pngwutil.c.
Version 1.6.26beta04 [October 3, 2016]
Quieted (bogus?) clang warnings about "absolute value has no effect"
when PNG_USE_ABS is defined.
Fixed offsets in contrib/intel/intel_sse.patch
Version 1.6.26beta05 [October 6, 2016]
Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h
to avoid a signed/unsigned compare in the preprocessor.
Version 1.6.26beta06 [October 7, 2016]
Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to
optionally avoid ADLER32 evaluation.
Version 1.6.26rc01 [October 12, 2016]
No changes.
Version 1.6.26 [October 20, 2016]
Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c
Despammed email addresses (replaced "@" with " at ").
Version 1.6.27beta01 [November 2, 2016]
Restrict the new ADLER32-skipping to IDAT chunks. It broke iCCP chunk
handling: an erroneous iCCP chunk would throw a png_error and reject the
entire PNG image instead of rejecting just the iCCP chunk with a warning,
if built with zlib-1.2.8.1.
Version 1.6.27rc01 [December 27, 2016]
Control ADLER32 checking with new PNG_IGNORE_ADLER32 option. Fixes
an endless loop when handling erroneous ADLER32 checksums; bug
introduced in libpng-1.6.26.
Removed the use of a macro containing the pre-processor 'defined'
operator. It is unclear whether this is valid; a macro that
"generates" 'defined' is not permitted, but the use of the word
"generates" within the C90 standard seems to imply more than simple
substitution of an expression itself containing a well-formed defined
operation.
Added ARM support to CMakeLists.txt (Andreas Franek).
Version 1.6.27 [December 29, 2016]
Fixed a potential null pointer dereference in png_set_text_2() (bug report
and patch by Patrick Keshishian, CVE-2016-10087).
Version 1.6.28rc01 [January 3, 2017]
Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna).
Added option to Cmake build allowing a custom location of zlib to be
specified in a scenario where libpng is being built as a subproject
alongside zlib by another project (Sam Serrels).
Changed png_ptr->options from a png_byte to png_uint_32, to accommodate
up to 16 options.
Version 1.6.28rc02 [January 4, 2017]
Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
Moved SSE2 optimization code into the main libpng source directory.
Configure libpng with "configure --enable-intel-sse" or compile
libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
Version 1.6.28rc03 [January 4, 2017]
Backed out the SSE optimization and last CMakeLists.txt to allow time for QA.
Version 1.6.28 [January 5, 2017]
No changes.
Version 1.6.29beta01 [January 12, 2017]
Readded "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna).
Moved SSE2 optimization code into the main libpng source directory.
Configure libpng with "configure --enable-intel-sse" or compile
libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it.
Simplified conditional compilation in pngvalid.c, for AIX (Michael Felt).
Version 1.6.29beta02 [February 22, 2017]
Avoid conditional directives that break statements in pngrutil.c (Romero
Malaquias)
The contrib/examples/pngtopng.c recovery code was in the wrong "if"
branches; the comments were correct.
Added code for PowerPC VSX optimisation (Vadim Barkov).
Version 1.6.29beta03 [March 1, 2017]
Avoid potential overflow of shift operations in png_do_expand() (Aaron Boxer).
Change test ZLIB_VERNUM >= 0x1281 to ZLIB_VERNUM >= 0x1290 in pngrutil.c
because Solaris 11 distributes zlib-1.2.8.f that is older than 1.2.8.1,
as suggested in zlib FAQ, item 24.
Suppress clang warnings about implicit sign changes in png.c
Version 1.6.29 [March 16, 2017]
No changes.
Version 1.6.30beta01 [April 1, 2017]
Added missing "$(CPPFLAGS)" to the compile line for c.pic.o in
makefile.linux and makefile.solaris-x86 (Cosmin).
Revised documentation of png_get_error_ptr() in the libpng manual.
Silence clang -Wcomma and const drop warnings (Viktor Szakats).
Update Sourceforge URLs in documentation (https instead of http).
Version 1.6.30beta02 [April 22, 2017]
Document need to check for integer overflow when allocating a pixel
buffer for multiple rows in contrib/gregbook, contrib/pngminus,
example.c, and in the manual (suggested by Jaeseung Choi). This
is similar to the bug reported against pngquant in CVE-2016-5735.
Removed reference to the obsolete PNG_SAFE_LIMITS macro in the documentation.
Version 1.6.30beta03 [May 22, 2017]
Check for integer overflow in contrib/visupng and contrib/tools/genpng.
Do not double evaluate CMAKE_SYSTEM_PROCESSOR in CMakeLists.txt.
Test CMAKE_HOST_WIN32 instead of WIN32 in CMakeLists.txt.
Fix some URL in documentation.
Version 1.6.30beta04 [June 7, 2017]
Avoid writing an empty IDAT when the last IDAT exactly fills the
compression buffer (bug report by Brian Baird). This bug was
introduced in libpng-1.6.0.
Version 1.6.30rc01 [June 14, 2017]
No changes.
Version 1.6.30rc02 [June 25, 2017]
Update copyright year in pnglibconf.h, make ltmain.sh executable.
Add a reference to the libpng.download site in README.
Version 1.6.30 [June 28, 2017]
No changes.
Version 1.6.31beta01 [July 5, 2017]
Guard the definition of _POSIX_SOURCE in pngpriv.h (AIX already defines it;
bug report by Michael Felt).
Revised pngpriv.h to work around failure to compile arm/filter_neon.S
("typedef" directive is unrecognized by the assembler). The problem
was introduced in libpng-1.6.30beta01.
Added "Requires: zlib" to libpng.pc.in (Pieter Neerincx).
Added special case for FreeBSD in arm/filter_neon.S (Maya Rashish).
Version 1.6.31beta02 [July 8, 2017]
Added instructions for disabling hardware optimizations in INSTALL.
Added "--enable-hardware-optimizations" configuration flag to enable
or disable all hardware optimizations with one flag.
Version 1.6.31beta03 [July 9, 2017]
Updated CMakeLists.txt to add INTEL_SSE and MIPS_MSA platforms.
Changed "int" to "png_size_t" in intel/filter_sse2.c to prevent
possible integer overflow (Bug report by John Bowler).
Quieted "declaration after statement" warnings in intel/filter_sse2.c.
Added scripts/makefile-linux-opt, which has hardware optimizations enabled.
Version 1.6.31beta04 [July 11, 2017]
Removed one of the GCC-7.1.0 'strict-overflow' warnings that result when
integers appear on both sides of a compare. Worked around the others by
forcing the strict-overflow setting in the relevant functions to a level
where they are not reported (John Bowler).
Changed "FALL THROUGH" comments to "FALLTHROUGH" because GCC doesn't like
the space.
Worked around some C-style casts from (void*) because g++ 5.4.0 objects
to them.
Increased the buffer size for 'sprint' to pass the gcc 7.1.0 'sprint
overflow' check that is on by default with -Wall -Wextra.
Version 1.6.31beta05 [July 13, 2017]
Added eXIf chunk support.
Version 1.6.31beta06 [July 17, 2017]
Added a minimal eXIf chunk (with Orientation and FocalLengthIn35mmFilm
tags) to pngtest.png.
Version 1.6.31beta07 [July 18, 2017]
Revised the eXIf chunk in pngtest.png to fix "Bad IFD1 Directory" warning.
Version 1.6.31rc01 [July 19, 2017]
No changes.
Version 1.6.31rc02 [July 25, 2017]
Fixed typo in example.c (png_free_image should be png_image_free) (Bug
report by John Smith)
Version 1.6.31 [July 27, 2017]
No changes.
Version 1.6.32beta01 [July 31, 2017]
Avoid possible NULL dereference in png_handle_eXIf when benign_errors
are allowed. Avoid leaking the input buffer "eXIf_buf".
Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif
to arguments for png_get_eXIf() and png_set_eXIf().
Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in
pngwrite.c, and made various other fixes to png_write_eXIf().
Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and
png_set_eXIf_1(), respectively, to avoid breaking API compatibility
with libpng-1.6.31.
Version 1.6.32beta02 [August 1, 2017]
Updated contrib/libtests/pngunknown.c with eXIf chunk.
Version 1.6.32beta03 [August 2, 2017]
Initialized btoa[] in pngstest.c
Stop memory leak when returning from png_handle_eXIf() with an error
(Bug report from the OSS-fuzz project).
Version 1.6.32beta04 [August 2, 2017]
Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf().
Update libpng.3 and libpng-manual.txt about eXIf functions.
Version 1.6.32beta05 [August 2, 2017]
Restored png_get_eXIf() and png_set_eXIf() to maintain API compatibility.
Version 1.6.32beta06 [August 2, 2017]
Removed png_get_eXIf_1() and png_set_eXIf_1().
Version 1.6.32beta07 [August 3, 2017]
Check length of all chunks except IDAT against user limit to fix an
OSS-fuzz issue (Fixes CVE-2017-12652).
Version 1.6.32beta08 [August 3, 2017]
Check length of IDAT against maximum possible IDAT size, accounting
for height, rowbytes, interlacing and zlib/deflate overhead.
Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf)
does not work (the eXIf chunk data can contain zeroes).
Version 1.6.32beta09 [August 3, 2017]
Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation,
no longer using deprecated cmake LOCATION feature (Clifford Yapp).
Fixed five-byte error in the calculation of IDAT maximum possible size.
Version 1.6.32beta10 [August 5, 2017]
Moved chunk-length check into a png_check_chunk_length() private
function (Suggested by Max Stepin).
Moved bad pngs from tests to contrib/libtests/crashers
Moved testing of bad pngs into a separate tests/pngtest-badpngs script
Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL
in the output but PASS for the libpng test.
Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp).
Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the
num_exif argument to png_get_eXIf_1() (Github Issue 171).
Version 1.6.32beta11 [August 7, 2017]
Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks().
Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers.
Make pngtest --strict, --relax, --xfail options imply -m (multiple).
Removed unused chunk_name parameter from png_check_chunk_length().
Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak.
Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue.
Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR.
Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue.
Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account
for the minimum 'deflate' stream, and relocate the test to a point
after the keyword has been read.
Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM".
Version 1.6.32rc01 [August 18, 2017]
Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers,
one for each known chunk type, with length = 2GB-1.
Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts
in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706,
and 162707).
Renamed chunks in contrib/testpngs/crashers to avoid having files whose
names differ only in case; this causes problems with some platforms
(github issue #172).
Version 1.6.32rc02 [August 22, 2017]
Added contrib/oss-fuzz directory which contains files used by the oss-fuzz
project (https://github.com/google/oss-fuzz/tree/master/projects/libpng).
Version 1.6.32 [August 24, 2017]
No changes.
Version 1.6.33beta01 [August 28, 2017]
Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing
parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse).
Fixed off-by-one error in png_do_check_palette_indexes() (Bug report
by Mick P., Source Forge Issue #269).
Version 1.6.33beta02 [September 3, 2017]
Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
to fix shortlived oss-fuzz issue 3234.
Compute a larger limit on IDAT because some applications write a deflate
buffer for each row (Bug report by Andrew Church).
Use current date (DATE) instead of release-date (RDATE) in last
changed date of contrib/oss-fuzz files.
Enabled ARM support in CMakeLists.txt (Bernd Kuhls).
Version 1.6.33beta03 [September 14, 2017]
Fixed incorrect typecast of some arguments to png_malloc() and
png_calloc() that were png_uint_32 instead of png_alloc_size_t
(Bug report by "irwir" in Github libpng issue #175).
Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github
issue 162, by rcdailey).
Version 1.6.33rc01 [September 20, 2017]
Initialize memory allocated by png_inflate to zero, using memset, to
stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2()
due to truncated iTXt or zTXt chunk.
Initialize memory allocated by png_read_buffer to zero, using memset, to
stop an oss-fuzz "use of uninitialized value" detection in
png_icc_check_tag_table() due to truncated iCCP chunk.
Removed a redundant test (suggested by "irwir" in Github issue #180).
Version 1.6.33rc02 [September 23, 2017]
Added an interlaced version of each file in contrib/pngsuite.
Relocate new memset() call in pngrutil.c.
Removed more redundant tests (suggested by "irwir" in Github issue #180).
Add support for loading images with associated alpha in the Simplified
API (Samuel Williams).
Version 1.6.33 [September 28, 2017]
Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state.
Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc
Add end_info structure and png_read_end() to the libpng fuzzer.
Version 1.6.34 [September 29, 2017]
Removed contrib/pngsuite/i*.png; some of them caused test failures.
Version 1.6.35beta01 [March 6, 2018]
Restored 21 of the contrib/pngsuite/i*.png, which do not cause test
failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png.
Added calls to png_set_*() transforms commonly used by browsers to
the fuzzer.
Removed some unnecessary brackets in pngrtran.c
Fixed miscellaneous typos (Patch by github user "luzpaz").
Change "ASM C" to "C ASM" in CMakeLists.txt
Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin)
Added hardware optimization directories to zip and 7z distributions.
Fixed incorrect bitmask for options.
Fixed many spelling typos.
Version 1.6.35beta02 [March 28, 2018]
Make png_get_iCCP consistent with man page (allow compression-type argument
to be NULL, bug report by Lenard Szolnoki).
Version 1.6.35 [July 15, 2018]
Replaced the remaining uses of png_size_t with size_t (Cosmin)
Fixed the calculation of row_factor in png_check_chunk_length
(reported by Thuan Pham in SourceForge issue #278)
Added missing parentheses to a macro definition
(suggested by "irwir" in GitHub issue #216)
Version 1.6.36 [December 1, 2018]
Optimized png_do_expand_palette for ARM processors.
Improved performance by around 10-22% on a recent ARM Chromebook.
(Contributed by Richard Townsend, ARM Holdings)
Fixed manipulation of machine-specific optimization options.
(Contributed by Vicki Pfau)
Used memcpy instead of manual pointer arithmetic on Intel SSE2.
(Contributed by Samuel Williams)
Fixed build errors with MSVC on ARM64.
(Contributed by Zhijie Liang)
Fixed detection of libm in CMakeLists.
(Contributed by Cameron Cawley)
Fixed incorrect creation of pkg-config file in CMakeLists.
(Contributed by Kyle Bentley)
Fixed the CMake build on Windows MSYS by avoiding symlinks.
Fixed a build warning on OpenBSD.
(Contributed by Theo Buehler)
Fixed various typos in comments.
(Contributed by "luz.paz")
Raised the minimum required CMake version from 3.0.2 to 3.1.
Removed yet more of the vestigial support for pre-ANSI C compilers.
Removed ancient makefiles for ancient systems that have been broken
across all previous libpng-1.6.x versions.
Removed the Y2K compliance statement and the export control
information.
Applied various code style and documentation fixes.
Version 1.6.37 [April 14, 2019]
Fixed a use-after-free vulnerability (CVE-2019-7317) in png_image_free.
Fixed a memory leak in the ARM NEON implementation of png_do_expand_palette.
Fixed a memory leak in pngtest.c.
Fixed two vulnerabilities (CVE-2018-14048, CVE-2018-14550) in
contrib/pngminus; refactor.
Changed the license of contrib/pngminus to MIT; refresh makefile and docs.
(Contributed by Willem van Schaik)
Fixed a typo in the libpng license v2.
(Contributed by Miguel Ojeda)
Added makefiles for AddressSanitizer-enabled builds.
Cleaned up various makefiles.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
to subscribe.

@ -1,58 +1,52 @@
# CMakeLists.txt # CMakeLists.txt
# Copyright (C) 2007,2009-2016 Glenn Randers-Pehrson # Copyright (C) 2018 Cosmin Truta
# Copyright (C) 2007,2009-2018 Glenn Randers-Pehrson
# Written by Christian Ehrlicher, 2007 # Written by Christian Ehrlicher, 2007
# Revised by Roger Lowman, 2009-2010 # Revised by Roger Lowman, 2009-2010
# Revised by Clifford Yapp, 2011-2012 # Revised by Clifford Yapp, 2011-2012,2017
# Revised by Roger Leigh, 2016 # Revised by Roger Leigh, 2016
# Revised by Andreas Franek, 2016
# Revised by Sam Serrels, 2017
# Revised by Vadim Barkov, 2017
# Revised by Vicky Pfau, 2018
# Revised by Cameron Cawley, 2018
# Revised by Cosmin Truta, 2018
# Revised by Kyle Bentley, 2018
# This code is released under the libpng license. # This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer # For conditions of distribution and use, see the disclaimer
# and license in png.h # and license in png.h
cmake_minimum_required(VERSION 2.8.3) cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 2.8.3) cmake_policy(VERSION 3.1)
# Set MacOSX @rpath usage globally. project(libpng C ASM)
if (POLICY CMP0020)
cmake_policy(SET CMP0020 NEW)
endif(POLICY CMP0020)
if (POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif(POLICY CMP0042)
# Use new variable expansion policy.
if (POLICY CMP0053)
cmake_policy(SET CMP0053 NEW)
endif(POLICY CMP0053)
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif(POLICY CMP0054)
set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
project(libpng C)
enable_testing() enable_testing()
set(PNGLIB_MAJOR 1) set(PNGLIB_MAJOR 1)
set(PNGLIB_MINOR 6) set(PNGLIB_MINOR 6)
set(PNGLIB_RELEASE 23) set(PNGLIB_RELEASE 37)
set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE}) set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
# needed packages include(GNUInstallDirs)
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIR})
if(NOT WIN32) # needed packages
find_library(M_LIBRARY
NAMES m # Allow users to specify location of Zlib.
PATHS /usr/lib /usr/local/lib # Useful if zlib is being built alongside this as a sub-project.
) option(PNG_BUILD_ZLIB "Custom zlib Location, else find_package is used" OFF)
if(NOT M_LIBRARY)
message(STATUS "math lib 'libm' not found; floating point support disabled") if(NOT PNG_BUILD_ZLIB)
endif() find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIR})
endif()
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
find_library(M_LIBRARY m)
else() else()
# not needed on windows # libm is not needed and/or not available
set(M_LIBRARY "") set(M_LIBRARY "")
endif() endif()
@ -63,12 +57,145 @@ option(PNG_TESTS "Build libpng tests" ON)
# Many more configuration options could be added here # Many more configuration options could be added here
option(PNG_FRAMEWORK "Build OS X framework" OFF) option(PNG_FRAMEWORK "Build OS X framework" OFF)
option(PNG_DEBUG "Build with debug output" OFF) option(PNG_DEBUG "Build with debug output" OFF)
option(PNGARG "Disable ANSI-C prototypes" OFF) option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON)
set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names") set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings") set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
if(PNG_HARDWARE_OPTIMIZATIONS)
# set definitions and sources for arm
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
check: (default) use internal checking code;
off: disable the optimizations;
on: turn on unconditionally.")
set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS
${PNG_ARM_NEON_POSSIBLE_VALUES})
list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
if(index EQUAL -1)
message(FATAL_ERROR
"PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
elseif(NOT ${PNG_ARM_NEON} STREQUAL "off")
set(libpng_arm_sources
arm/arm_init.c
arm/filter_neon.S
arm/filter_neon_intrinsics.c
arm/palette_neon_intrinsics.c)
if(${PNG_ARM_NEON} STREQUAL "on")
add_definitions(-DPNG_ARM_NEON_OPT=2)
elseif(${PNG_ARM_NEON} STREQUAL "check")
add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED)
endif()
else()
add_definitions(-DPNG_ARM_NEON_OPT=0)
endif()
endif()
# set definitions and sources for powerpc
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations:
off: disable the optimizations.")
set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS
${PNG_POWERPC_VSX_POSSIBLE_VALUES})
list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
if(index EQUAL -1)
message(FATAL_ERROR
"PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "off")
set(libpng_powerpc_sources
powerpc/powerpc_init.c
powerpc/filter_vsx_intrinsics.c)
if(${PNG_POWERPC_VSX} STREQUAL "on")
add_definitions(-DPNG_POWERPC_VSX_OPT=2)
endif()
else()
add_definitions(-DPNG_POWERPC_VSX_OPT=0)
endif()
endif()
# set definitions and sources for intel
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations:
off: disable the optimizations")
set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS
${PNG_INTEL_SSE_POSSIBLE_VALUES})
list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
if(index EQUAL -1)
message(FATAL_ERROR
"PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
elseif(NOT ${PNG_INTEL_SSE} STREQUAL "off")
set(libpng_intel_sources
intel/intel_init.c
intel/filter_sse2_intrinsics.c)
if(${PNG_INTEL_SSE} STREQUAL "on")
add_definitions(-DPNG_INTEL_SSE_OPT=1)
endif()
else()
add_definitions(-DPNG_INTEL_SSE_OPT=0)
endif()
endif()
# set definitions and sources for MIPS
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations:
off: disable the optimizations")
set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS
${PNG_MIPS_MSA_POSSIBLE_VALUES})
list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index)
if(index EQUAL -1)
message(FATAL_ERROR
"PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
elseif(NOT ${PNG_MIPS_MSA} STREQUAL "off")
set(libpng_mips_sources
mips/mips_init.c
mips/filter_msa_intrinsics.c)
if(${PNG_MIPS_MSA} STREQUAL "on")
add_definitions(-DPNG_MIPS_MSA_OPT=2)
endif()
else()
add_definitions(-DPNG_MIPS_MSA_OPT=0)
endif()
endif()
else(PNG_HARDWARE_OPTIMIZATIONS)
# set definitions and sources for arm
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
add_definitions(-DPNG_ARM_NEON_OPT=0)
endif()
# set definitions and sources for powerpc
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
add_definitions(-DPNG_POWERPC_VSX_OPT=0)
endif()
# set definitions and sources for intel
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
add_definitions(-DPNG_INTEL_SSE_OPT=0)
endif()
# set definitions and sources for MIPS
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
add_definitions(-DPNG_MIPS_MSA_OPT=0)
endif()
endif(PNG_HARDWARE_OPTIMIZATIONS)
# SET LIBNAME # SET LIBNAME
set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
@ -124,17 +251,17 @@ function(symbol_prefix)
foreach(line ${OUT}) foreach(line ${OUT})
string(REGEX MATCH "^PREFIX=" found_match "${line}") string(REGEX MATCH "^PREFIX=" found_match "${line}")
if(found_match) if(found_match)
STRING(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}") string(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}")
string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}") string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}")
if(found_match) if(found_match)
STRING(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}") string(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}")
endif() endif()
set(SYMBOL_PREFIX "${prefix}") set(SYMBOL_PREFIX "${prefix}")
endif() endif()
endforeach() endforeach()
message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}") message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}")
set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE) set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE)
endfunction() endfunction()
if(UNIX) if(UNIX)
@ -145,7 +272,7 @@ find_program(AWK NAMES gawk awk)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(NOT AWK) if(NOT AWK OR ANDROID)
# No awk available to generate sources; use pre-built pnglibconf.h # No awk available to generate sources; use pre-built pnglibconf.h
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
@ -159,11 +286,11 @@ else()
set(oneValueArgs INPUT OUTPUT) set(oneValueArgs INPUT OUTPUT)
set(multiValueArgs DEPENDS) set(multiValueArgs DEPENDS)
cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT _GC_INPUT) if(NOT _GC_INPUT)
message(FATAL_ERROR "Invalid arguments. generate_out requires input.") message(FATAL_ERROR "generate_chk: Missing INPUT argument")
endif() endif()
if (NOT _GC_OUTPUT) if(NOT _GC_OUTPUT)
message(FATAL_ERROR "Invalid arguments. generate_out requires output.") message(FATAL_ERROR "generate_chk: Missing OUTPUT argument")
endif() endif()
add_custom_command(OUTPUT "${_GC_OUTPUT}" add_custom_command(OUTPUT "${_GC_OUTPUT}"
@ -182,11 +309,11 @@ else()
set(oneValueArgs INPUT OUTPUT) set(oneValueArgs INPUT OUTPUT)
set(multiValueArgs DEPENDS) set(multiValueArgs DEPENDS)
cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT _GO_INPUT) if(NOT _GO_INPUT)
message(FATAL_ERROR "Invalid arguments. generate_out requires input.") message(FATAL_ERROR "generate_out: Missing INPUT argument")
endif() endif()
if (NOT _GO_OUTPUT) if(NOT _GO_OUTPUT)
message(FATAL_ERROR "Invalid arguments. generate_out requires output.") message(FATAL_ERROR "generate_out: Missing OUTPUT argument")
endif() endif()
add_custom_command(OUTPUT "${_GO_OUTPUT}" add_custom_command(OUTPUT "${_GO_OUTPUT}"
@ -205,8 +332,8 @@ else()
set(oneValueArgs OUTPUT) set(oneValueArgs OUTPUT)
set(multiValueArgs DEPENDS) set(multiValueArgs DEPENDS)
cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT _GSO_OUTPUT) if(NOT _GSO_OUTPUT)
message(FATAL_ERROR "Invalid arguments. generate_source requires output.") message(FATAL_ERROR "generate_source: Missing OUTPUT argument")
endif() endif()
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}" add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}"
@ -307,7 +434,7 @@ else()
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
# A single target handles generation of all generated files. If # A single target handles generation of all generated files. If
# they are dependend upon separately by multiple targets, this # they are depended upon separately by multiple targets, this
# confuses parallel make (it would require a separate top-level # confuses parallel make (it would require a separate top-level
# target for each file to track the dependencies properly). # target for each file to track the dependencies properly).
add_custom_target(genfiles DEPENDS add_custom_target(genfiles DEPENDS
@ -324,7 +451,7 @@ else()
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
"${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out") "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
endif(NOT AWK) endif(NOT AWK OR ANDROID)
# OUR SOURCES # OUR SOURCES
set(libpng_public_hdrs set(libpng_public_hdrs
@ -338,7 +465,7 @@ set(libpng_private_hdrs
pnginfo.h pnginfo.h
pngstruct.h pngstruct.h
) )
if(AWK) if(AWK AND NOT ANDROID)
list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h") list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
endif() endif()
set(libpng_sources set(libpng_sources
@ -359,6 +486,10 @@ set(libpng_sources
pngwrite.c pngwrite.c
pngwtran.c pngwtran.c
pngwutil.c pngwutil.c
${libpng_arm_sources}
${libpng_intel_sources}
${libpng_mips_sources}
${libpng_powerpc_sources}
) )
set(pngtest_sources set(pngtest_sources
pngtest.c pngtest.c
@ -384,7 +515,7 @@ set(png_fix_itxt_sources
if(MSVC) if(MSVC)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
endif(MSVC) endif()
if(PNG_DEBUG) if(PNG_DEBUG)
add_definitions(-DPNG_DEBUG) add_definitions(-DPNG_DEBUG)
@ -464,7 +595,7 @@ if(NOT PNG_LIB_TARGETS)
message(SEND_ERROR message(SEND_ERROR
"No library variant selected to build. " "No library variant selected to build. "
"Please enable at least one of the following options: " "Please enable at least one of the following options: "
" PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK") "PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
endif() endif()
if(PNG_SHARED AND WIN32) if(PNG_SHARED AND WIN32)
@ -477,11 +608,11 @@ function(png_add_test)
set(multiValueArgs OPTIONS FILES) set(multiValueArgs OPTIONS FILES)
cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT _PAT_NAME) if(NOT _PAT_NAME)
message(FATAL_ERROR "Invalid arguments. png_add_test requires name.") message(FATAL_ERROR "png_add_test: Missing NAME argument")
endif() endif()
if (NOT _PAT_COMMAND) if(NOT _PAT_COMMAND)
message(FATAL_ERROR "Invalid arguments. png_add_test requires command.") message(FATAL_ERROR "png_add_test: Missing COMMAND argument")
endif() endif()
set(TEST_OPTIONS "${_PAT_OPTIONS}") set(TEST_OPTIONS "${_PAT_OPTIONS}")
@ -489,19 +620,11 @@ function(png_add_test)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in" configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY) "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY)
if(CMAKE_MAJOR_VERSION GREATER 2) # have generator expressions add_test(NAME "${_PAT_NAME}"
add_test(NAME "${_PAT_NAME}" COMMAND "${CMAKE_COMMAND}"
COMMAND "${CMAKE_COMMAND}" "-DLIBPNG=$<TARGET_FILE:png>"
"-DLIBPNG=$<TARGET_FILE:png>" "-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>"
"-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>" -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
-P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
else() # old 2.x add_test; limited and won't work well on Windows
# Note LIBPNG is a dummy value as there are no generator expressions
add_test("${_PAT_NAME}" "${CMAKE_COMMAND}"
"-DLIBPNG=${CMAKE_CURRENT_BINARY_DIR}/libpng.so"
"-DTEST_COMMAND=./${_PAT_COMMAND}"
-P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
endif()
endfunction() endfunction()
if(PNG_TESTS AND PNG_SHARED) if(PNG_TESTS AND PNG_SHARED)
@ -566,11 +689,11 @@ if(PNG_TESTS AND PNG_SHARED)
set(TEST_PNG_VALID TRUE) set(TEST_PNG_VALID TRUE)
if(TEST_PNG_ALPHA) if(TEST_PNG_ALPHA)
if (NOT "${alpha_type}" STREQUAL "alpha") if(NOT "${alpha_type}" STREQUAL "alpha")
set(TEST_PNG_VALID FALSE) set(TEST_PNG_VALID FALSE)
endif() endif()
else() else()
if ("${alpha_type}" STREQUAL "alpha") if("${alpha_type}" STREQUAL "alpha")
set(TEST_PNG_VALID FALSE) set(TEST_PNG_VALID FALSE)
endif() endif()
endif() endif()
@ -634,31 +757,51 @@ if(PNG_SHARED)
list(APPEND PNG_BIN_TARGETS png-fix-itxt) list(APPEND PNG_BIN_TARGETS png-fix-itxt)
endif() endif()
# Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set
IF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "lib")
ENDIF(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
# Set a variable with CMake code which: # Set a variable with CMake code which:
# Creates a symlink from src to dest (if possible) or alternatively # Creates a symlink from src to dest (if possible) or alternatively
# copies if different. # copies if different.
macro(CREATE_SYMLINK SRC_FILE DEST_FILE) include(CMakeParseArguments)
FILE(REMOVE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
if(WIN32 AND NOT CYGWIN AND NOT MSYS) function(create_symlink DEST_FILE)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE} cmake_parse_arguments(S "" "FILE;TARGET" "" ${ARGN})
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" ${CMAKE_CURRENT_BINARY_DIR}/${DEST_FILE} if(NOT S_TARGET AND NOT S_FILE)
DEPENDS ${PNG_LIB_TARGETS} message(FATAL_ERROR "create_symlink: Missing TARGET or FILE argument")
) endif()
ADD_CUSTOM_TARGET(${DEST_FILE}_COPY ALL DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE})
else(WIN32 AND NOT CYGWIN AND NOT MSYS) if(S_TARGET AND S_FILE)
get_filename_component(LINK_TARGET "${SRC_FILE}" NAME) message(FATAL_ERROR "create_symlink: Both source file ${S_FILE} and build target ${S_TARGET} arguments are present; can only have one.")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${LINK_TARGET}" ${DEST_FILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) if(S_FILE)
endif(WIN32 AND NOT CYGWIN AND NOT MSYS) # If we don't need to symlink something that's coming from a build target,
endmacro() # we can go ahead and symlink/copy at configure time.
if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
execute_process(
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
else()
execute_process(
COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
endif()
if(S_TARGET)
# We need to use generator expressions, which can be a bit tricky, so for
# simplicity make the symlink a POST_BUILD step and use the TARGET
# signature of add_custom_command.
if(CMAKE_HOST_WIN32 AND NOT CYGWIN)
add_custom_command(TARGET ${S_TARGET} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
else()
add_custom_command(TARGET ${S_TARGET} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E create_symlink $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE})
endif()
endif()
endfunction()
# Create source generation scripts. # Create source generation scripts.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
@ -668,111 +811,97 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY) ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY)
# libpng is a library so default to 'lib' # libpng is a library so default to 'lib'
if(NOT DEFINED CMAKE_INSTALL_LIBDIR) if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR lib) set(CMAKE_INSTALL_LIBDIR lib)
endif(NOT DEFINED CMAKE_INSTALL_LIBDIR) endif()
# CREATE PKGCONFIG FILES # CREATE PKGCONFIG FILES
# we use the same files like ./configure, so we have to set its vars # We use the same files like ./configure, so we have to set its vars.
# Only do this on Windows for Cygwin - the files don't make much sense outside # Only do this on Windows for Cygwin - the files don't make much sense outside
# a UNIX look alike # of a UNIX look-alike.
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
set(prefix ${CMAKE_INSTALL_PREFIX}) set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix ${CMAKE_INSTALL_PREFIX})
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
set(includedir ${CMAKE_INSTALL_PREFIX}/include) set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
set(LIBS "-lz -lm") set(LIBS "-lz -lm")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY) ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
CREATE_SYMLINK(${PNGLIB_NAME}.pc libpng.pc) create_symlink(libpng.pc FILE ${PNGLIB_NAME}.pc)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY) ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
CREATE_SYMLINK(${PNGLIB_NAME}-config libpng-config) create_symlink(libpng-config FILE ${PNGLIB_NAME}-config)
endif(NOT WIN32 OR CYGWIN OR MINGW) endif()
# SET UP LINKS # SET UP LINKS
if(PNG_SHARED) if(PNG_SHARED)
set_target_properties(png PROPERTIES set_target_properties(png PROPERTIES
# VERSION 16.${PNGLIB_RELEASE}.1.6.23 # VERSION 16.${PNGLIB_RELEASE}.1.6.37
VERSION 16.${PNGLIB_RELEASE}.0 VERSION 16.${PNGLIB_RELEASE}.0
SOVERSION 16 SOVERSION 16
CLEAN_DIRECT_OUTPUT 1) CLEAN_DIRECT_OUTPUT 1)
endif() endif()
# If CMake > 2.4.x, we set a variable used below to export
# targets to an export file.
# TODO: Use VERSION_GREATER after our cmake_minimum_required >= 2.6.2
if(CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 4)
set(PNG_EXPORT_RULE EXPORT libpng)
elseif(CMAKE_MAJOR_VERSION GREATER 2) # future proof
set(PNG_EXPORT_RULE EXPORT libpng)
endif()
# INSTALL # INSTALL
if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
install(TARGETS ${PNG_LIB_TARGETS} install(TARGETS ${PNG_LIB_TARGETS}
${PNG_EXPORT_RULE} EXPORT libpng
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}) FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(PNG_SHARED) if(PNG_SHARED)
# Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
if(CYGWIN OR MINGW) if(CYGWIN OR MINGW)
get_target_property(BUILD_TARGET_LOCATION png LOCATION_${CMAKE_BUILD_TYPE}) create_symlink(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png)
CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}) install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX}
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif()
endif(CYGWIN OR MINGW)
if(NOT WIN32) if(NOT WIN32)
get_target_property(BUILD_TARGET_LOCATION png LOCATION_${CMAKE_BUILD_TYPE}) create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png)
CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_SHARED_LIBRARY_SUFFIX}) install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX}
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif()
endif(NOT WIN32) endif()
endif(PNG_SHARED)
if(PNG_STATIC) if(PNG_STATIC)
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
get_target_property(BUILD_TARGET_LOCATION png_static LOCATION_${CMAKE_BUILD_TYPE}) create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
CREATE_SYMLINK(${BUILD_TARGET_LOCATION} libpng${CMAKE_STATIC_LIBRARY_SUFFIX}) install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX}
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif()
endif(NOT WIN32 OR CYGWIN OR MINGW) endif()
endif()
endif() endif()
if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
install(FILES ${libpng_public_hdrs} DESTINATION include) install(FILES ${libpng_public_hdrs} DESTINATION include)
install(FILES ${libpng_public_hdrs} DESTINATION include/${PNGLIB_NAME}) install(FILES ${libpng_public_hdrs} DESTINATION include/${PNGLIB_NAME})
endif() endif()
if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL)
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT WIN32 OR CYGWIN OR MINGW)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config DESTINATION bin)
DESTINATION bin) endif()
endif(NOT WIN32 OR CYGWIN OR MINGW)
endif() endif()
if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL)
install(TARGETS ${PNG_BIN_TARGETS} install(TARGETS ${PNG_BIN_TARGETS}
RUNTIME DESTINATION bin) RUNTIME DESTINATION bin)
endif() endif()
if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL)
# Install man pages # Install man pages
if(NOT PNG_MAN_DIR) if(NOT PNG_MAN_DIR)
set(PNG_MAN_DIR "share/man") set(PNG_MAN_DIR "share/man")
endif() endif()
install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3) install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3)
install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5) install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5)
# Install pkg-config files # Install pkg-config files
if(NOT WIN32 OR CYGWIN OR MINGW) if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
@ -781,12 +910,11 @@ if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
DESTINATION bin) DESTINATION bin)
endif(NOT WIN32 OR CYGWIN OR MINGW) endif()
endif() endif()
# On versions of CMake that support it, create an export file CMake # Create an export file that CMake users can include() to import our targets.
# users can include() to import our targets if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL)
if(PNG_EXPORT_RULE AND NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL )
install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake) install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)
endif() endif()
@ -801,4 +929,3 @@ endif()
# to create msvc import lib for mingw compiled shared lib # to create msvc import lib for mingw compiled shared lib
# pexports libpng.dll > libpng.def # pexports libpng.dll > libpng.def
# lib /def:libpng.def /machine:x86 # lib /def:libpng.def /machine:x86

@ -1,389 +0,0 @@
Installing libpng
Contents
I. Simple installation
II. Rebuilding the configure scripts
III. Using scripts/makefile*
IV. Using cmake
V. Directory structure
VI. Building with project files
VII. Building with makefiles
VIII. Configuring libpng for 16-bit platforms
IX. Configuring for DOS
X. Configuring for Medium Model
XI. Prepending a prefix to exported symbols
XII. Configuring for compiler xxx:
XIII. Removing unwanted object code
XIV. Changes to the build and configuration of libpng in libpng-1.5.x
XV. Setjmp/longjmp issues
XVI. Other sources of information about libpng
I. Simple installation
On Unix/Linux and similar systems, you can simply type
./configure [--prefix=/path]
make check
make install
and ignore the rest of this document. "/path" is the path to the directory
where you want to install the libpng "lib", "include", and "bin"
subdirectories.
If you downloaded a GIT clone, you will need to run ./autogen.sh before
running ./configure, to create "configure" and "Makefile.in" which are
not included in the GIT repository.
Note that "configure" is only included in the "*.tar" distributions and not
in the "*.zip" or "*.7z" distributions. If you downloaded one of those
distributions, see "Building with project files" or "Building with makefiles",
below.
II. Rebuilding the configure scripts
If configure does not work on your system, or if you have a need to
change configure.ac or Makefile.am, and you have a reasonably
up-to-date set of tools, running ./autogen.sh in a git clone before
running ./configure may fix the problem. To be really sure that you
aren't using any of the included pre-built scripts, especially if you
are building from a tar distribution instead of a git distribution,
do this:
./configure --enable-maintainer-mode
make maintainer-clean
./autogen.sh --maintainer --clean
./autogen.sh --maintainer
./configure [--prefix=/path] [other options]
make
make install
make check
III. Using scripts/makefile*
Instead, you can use one of the custom-built makefiles in the
"scripts" directory
cp scripts/pnglibconf.h.prebuilt pnglibconf.h
cp scripts/makefile.system makefile
make test
make install
The files that are presently available in the scripts directory
are listed and described in scripts/README.txt.
Or you can use one of the "projects" in the "projects" directory.
Before installing libpng, you must first install zlib, if it
is not already on your system. zlib can usually be found
wherever you got libpng; otherwise go to http://zlib.net. You can place
zlib in in the same directory as libpng or in another directory.
If your system already has a preinstalled zlib you will still need
to have access to the zlib.h and zconf.h include files that
correspond to the version of zlib that's installed.
If you wish to test with a particular zlib that is not first in the
standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS,
and LD_LIBRARY_PATH in your environment before running "make test"
or "make distcheck":
ZLIBLIB=/path/to/lib export ZLIBLIB
ZLIBINC=/path/to/include export ZLIBINC
CPPFLAGS="-I$ZLIBINC" export CPPFLAGS
LDFLAGS="-L$ZLIBLIB" export LDFLAGS
LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH
If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC
in your environment and type "make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test".
IV. Using cmake
If you want to use "cmake" (see www.cmake.org), type
cmake . -DCMAKE_INSTALL_PREFIX=/path
make
make install
As when using the simple configure method described above, "/path" points to
the installation directory where you want to put the libpng "lib", "include",
and "bin" subdirectories.
V. Directory structure
You can rename the directories that you downloaded (they
might be called "libpng-x.y.z" or "libpngNN" and "zlib-1.2.8"
or "zlib128") so that you have directories called "zlib" and "libpng".
Your directory structure should look like this:
.. (the parent directory)
libpng (this directory)
INSTALL (this file)
README
*.h, *.c => libpng source files
CMakeLists.txt => "cmake" script
configuration files:
configure.ac, configure, Makefile.am, Makefile.in,
autogen.sh, config.guess, ltmain.sh, missing, libpng.pc.in,
libpng-config.in, aclocal.m4, config.h.in, config.sub,
depcomp, install-sh, mkinstalldirs, test-pngtest.sh
contrib
arm-neon, conftest, examples, gregbook, libtests, pngminim,
pngminus, pngsuite, tools, visupng
projects
cbuilder5, owatcom, visualc71, vstudio, xcode
scripts
makefile.*
*.def (module definition files)
etc.
pngtest.png
etc.
zlib
README, *.h, *.c contrib, etc.
If the line endings in the files look funny, you may wish to get the other
distribution of libpng. It is available in both tar.gz (UNIX style line
endings) and zip (DOS style line endings) formats.
VI. Building with project files
If you are building libpng with MSVC, you can enter the
libpng projects\visualc71 or vstudio directory and follow the instructions
in README.txt.
Otherwise enter the zlib directory and follow the instructions in zlib/README,
then come back here and run "configure" or choose the appropriate
makefile.sys in the scripts directory.
VII. Building with makefiles
Copy the file (or files) that you need from the
scripts directory into this directory, for example
MSDOS example: copy scripts\makefile.msc makefile
copy scripts\pnglibconf.h.prebuilt pnglibconf.h
UNIX example: cp scripts/makefile.std makefile
cp scripts/pnglibconf.h.prebuilt pnglibconf.h
Read the makefile to see if you need to change any source or
target directories to match your preferences.
Then read pnglibconf.dfa to see if you want to make any configuration
changes.
Then just run "make" which will create the libpng library in
this directory and "make test" which will run a quick test that reads
the "pngtest.png" file and writes a "pngout.png" file that should be
identical to it. Look for "9782 zero samples" in the output of the
test. For more confidence, you can run another test by typing
"pngtest pngnow.png" and looking for "289 zero samples" in the output.
Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare
your output with the result shown in contrib/pngsuite/README.
Most of the makefiles will allow you to run "make install" to
put the library in its final resting place (if you want to
do that, run "make install" in the zlib directory first if necessary).
Some also allow you to run "make test-installed" after you have
run "make install".
VIII. Configuring libpng for 16-bit platforms
You will want to look into zconf.h to tell zlib (and thus libpng) that
it cannot allocate more than 64K at a time. Even if you can, the memory
won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
IX. Configuring for DOS
For DOS users who only have access to the lower 640K, you will
have to limit zlib's memory usage via a png_set_compression_mem_level()
call. See zlib.h or zconf.h in the zlib library for more information.
X. Configuring for Medium Model
Libpng's support for medium model has been tested on most of the popular
compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
defined, and FAR gets defined to far in pngconf.h, and you should be
all set. Everything in the library (except for zlib's structure) is
expecting far data. You must use the typedefs with the p or pp on
the end for pointers (or at least look at them and be careful). Make
note that the rows of data are defined as png_bytepp, which is
an "unsigned char far * far *".
XI. Prepending a prefix to exported symbols
Starting with libpng-1.6.0, you can configure libpng (when using the
"configure" script) to prefix all exported symbols by means of the
configuration option "--with-libpng-prefix=FOO_", where FOO_ can be any
string beginning with a letter and containing only uppercase
and lowercase letters, digits, and the underscore (i.e., a C language
identifier). This creates a set of macros in pnglibconf.h, so this is
transparent to applications; their function calls get transformed by
the macros to use the modified names.
XII. Configuring for compiler xxx:
All includes for libpng are in pngconf.h. If you need to add, change
or delete an include, this is the place to do it.
The includes that are not needed outside libpng are placed in pngpriv.h,
which is only used by the routines inside libpng itself.
The files in libpng proper only include pngpriv.h and png.h, which
in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h.
As of libpng-1.5.0, pngpriv.h also includes three other private header
files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material
that previously appeared in the public headers.
XIII. Removing unwanted object code
There are a bunch of #define's in pngconf.h that control what parts of
libpng are compiled. All the defines end in _SUPPORTED. If you are
never going to use a capability, you can change the #define to #undef
before recompiling libpng and save yourself code and data space, or
you can turn off individual capabilities with defines that begin with
PNG_NO_.
In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead.
You can also turn all of the transforms and ancillary chunk capabilities
off en masse with compiler directives that define
PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
or all four, along with directives to turn on any of the capabilities that
you do want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the
extra transformations but still leave the library fully capable of reading
and writing PNG files with all known public chunks. Use of the
PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library
that is incapable of reading or writing ancillary chunks. If you are
not using the progressive reading capability, you can turn that off
with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING
capability, which you'll still have).
All the reading and writing specific code are in separate files, so the
linker should only grab the files it needs. However, if you want to
make sure, or if you are building a stand alone library, all the
reading files start with "pngr" and all the writing files start with "pngw".
The files that don't match either (like png.c, pngtrans.c, etc.)
are used for both reading and writing, and always need to be included.
The progressive reader is in pngpread.c
If you are creating or distributing a dynamically linked library (a .so
or DLL file), you should not remove or disable any parts of the library,
as this will cause applications linked with different versions of the
library to fail if they call functions not available in your library.
The size of the library itself should not be an issue, because only
those sections that are actually used will be loaded into memory.
XIV. Changes to the build and configuration of libpng in libpng-1.5.x
Details of internal changes to the library code can be found in the CHANGES
file and in the GIT repository logs. These will be of no concern to the vast
majority of library users or builders; however, the few who configure libpng
to a non-default feature set may need to change how this is done.
There should be no need for library builders to alter build scripts if
these use the distributed build support - configure or the makefiles -
however, users of the makefiles may care to update their build scripts
to build pnglibconf.h where the corresponding makefile does not do so.
Building libpng with a non-default configuration has changed completely.
The old method using pngusr.h should still work correctly even though the
way pngusr.h is used in the build has been changed; however, library
builders will probably want to examine the changes to take advantage of
new capabilities and to simplify their build system.
A. Specific changes to library configuration capabilities
The exact mechanism used to control attributes of API functions has
changed. A single set of operating system independent macro definitions
is used and operating system specific directives are defined in
pnglibconf.h
As part of this the mechanism used to choose procedure call standards on
those systems that allow a choice has been changed. At present this only
affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems
running on Intel processors. As before, PNGAPI is defined where required
to control the exported API functions; however, two new macros, PNGCBAPI
and PNGCAPI, are used instead for callback functions (PNGCBAPI) and
(PNGCAPI) for functions that must match a C library prototype (currently
only png_longjmp_ptr, which must match the C longjmp function.) The new
approach is documented in pngconf.h
Despite these changes, libpng 1.5.0 only supports the native C function
calling standard on those platforms tested so far (__cdecl on Microsoft
Windows). This is because the support requirements for alternative
calling conventions seem to no longer exist. Developers who find it
necessary to set PNG_API_RULE to 1 should advise the mailing list
(png-mng-implement) of this and library builders who use Openwatcom and
therefore set PNG_API_RULE to 2 should also contact the mailing list.
B. Changes to the configuration mechanism
Prior to libpng-1.5.0 library builders who needed to configure libpng
had either to modify the exported pngconf.h header file to add system
specific configuration or had to write feature selection macros into
pngusr.h and cause this to be included into pngconf.h by defining
PNG_USER_CONFIG. The latter mechanism had the disadvantage that an
application built without PNG_USER_CONFIG defined would see the
unmodified, default, libpng API and thus would probably fail to link.
These mechanisms still work in the configure build and in any makefile
build that builds pnglibconf.h, although the feature selection macros
have changed somewhat as described above. In 1.5.0, however, pngusr.h is
processed only once, at the time the exported header file pnglibconf.h is
built. pngconf.h no longer includes pngusr.h; therefore, pngusr.h is ignored
after the build of pnglibconf.h and it is never included in an application
build.
The formerly used alternative of adding a list of feature macros to the
CPPFLAGS setting in the build also still works; however, the macros will be
copied to pnglibconf.h and this may produce macro redefinition warnings
when the individual C files are compiled.
All configuration now only works if pnglibconf.h is built from
scripts/pnglibconf.dfa. This requires the program awk. Brian Kernighan
(the original author of awk) maintains C source code of that awk and this
and all known later implementations (often called by subtly different
names - nawk and gawk for example) are adequate to build pnglibconf.h.
The Sun Microsystems (now Oracle) program 'awk' is an earlier version
and does not work; this may also apply to other systems that have a
functioning awk called 'nawk'.
Configuration options are now documented in scripts/pnglibconf.dfa. This
file also includes dependency information that ensures a configuration is
consistent; that is, if a feature is switched off, dependent features are
also switched off. As a recommended alternative to using feature macros in
pngusr.h a system builder may also define equivalent options in pngusr.dfa
(or, indeed, any file) and add that to the configuration by setting
DFA_XTRA to the file name. The makefiles in contrib/pngminim illustrate
how to do this, and also illustrate a case where pngusr.h is still required.
After you have built libpng, the definitions that were recorded in
pnglibconf.h are available to your application (pnglibconf.h is included
in png.h and gets installed alongside png.h and pngconf.h in your
$PREFIX/include directory). Do not edit pnglibconf.h after you have built
libpng, because than the settings would not accurately reflect the settings
that were used to build libpng.
XV. Setjmp/longjmp issues
Libpng uses setjmp()/longjmp() for error handling. Unfortunately setjmp()
is known to be not thread-safe on some platforms and we don't know of
any platform where it is guaranteed to be thread-safe. Therefore, if
your application is going to be using multiple threads, you should
configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with
-DPNG_NO_SETJMP on your compile line, or with
#undef PNG_SETJMP_SUPPORTED
in your pnglibconf.h or pngusr.h.
Starting with libpng-1.6.0, the library included a "simplified API".
This requires setjmp/longjmp, so you must either build the library
with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED
and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined.
XVI. Other sources of information about libpng:
Further information can be found in the README and libpng-manual.txt
files, in the individual makefiles, in png.h, and the manual pages
libpng.3 and png.5.

@ -1,50 +1,82 @@
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
=========================================
This copy of the libpng notices is provided for your convenience. In case of PNG Reference Library License version 2
any discrepancy between this copy and the notices in the file png.h that is ---------------------------------------
included in the libpng distribution, the latter shall prevail.
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: * Copyright (c) 1995-2019 The PNG Reference Library Authors.
* Copyright (c) 2018-2019 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.
If you modify libpng you may insert additional notices immediately following The software is supplied "as is", without warranty of any kind,
this sentence. 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.
This code is released under the libpng license. 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:
libpng versions 1.0.7, July 1, 2000 through 1.6.23, June 9, 2016 are 1. The origin of this software must not be misrepresented; you
Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are 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 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 disclaimer and license as libpng-1.0.6 with the following individuals
added to the list of Contributing Authors: added to the list of Contributing Authors:
Simon-Pierre Cadieux Simon-Pierre Cadieux
Eric S. Raymond Eric S. Raymond
Mans Rullgard Mans Rullgard
Cosmin Truta Cosmin Truta
Gilles Vollant Gilles Vollant
James Yu James Yu
Mandar Sahastrabuddhe
Google Inc.
Vadim Barkov
and with the following additions to the disclaimer: and with the following additions to the disclaimer:
There is no warranty against interference with your enjoyment of the There is no warranty against interference with your enjoyment of
library or against infringement. There is no warranty that our the library or against infringement. There is no warranty that our
efforts or the library will fulfill any of your particular purposes efforts or the library will fulfill any of your particular purposes
or needs. This library is provided with all faults, and the entire or needs. This library is provided with all faults, and the entire
risk of satisfactory quality, performance, accuracy, and effort is with risk of satisfactory quality, performance, accuracy, and effort is
the user. with the user.
Some files in the "contrib" directory and some configure-generated Some files in the "contrib" directory and some configure-generated
files that are distributed with libpng have other copyright owners and files that are distributed with libpng have other copyright owners, and
are released under other open source licenses. are released under other open source licenses.
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
libpng-0.96, and are distributed according to the same disclaimer and 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 license as libpng-0.96, with the following individuals added to the
of Contributing Authors: list of Contributing Authors:
Tom Lane Tom Lane
Glenn Randers-Pehrson Glenn Randers-Pehrson
Willem van Schaik Willem van Schaik
libpng versions 0.89, June 1996, through 0.96, May 1997, are libpng versions 0.89, June 1996, through 0.96, May 1997, are
Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
@ -52,14 +84,14 @@ and are distributed according to the same disclaimer and license as
libpng-0.88, with the following individuals added to the list of libpng-0.88, with the following individuals added to the list of
Contributing Authors: Contributing Authors:
John Bowler John Bowler
Kevin Bracey Kevin Bracey
Sam Bushell Sam Bushell
Magnus Holmgren Magnus Holmgren
Greg Roelofs Greg Roelofs
Tom Tanner Tom Tanner
Some files in the "scripts" directory have other copyright owners Some files in the "scripts" directory have other copyright owners,
but are released under this license. but are released under this license.
libpng versions 0.5, May 1995, through 0.88, January 1996, are libpng versions 0.5, May 1995, through 0.88, January 1996, are
@ -68,63 +100,35 @@ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
For the purposes of this copyright and license, "Contributing Authors" For the purposes of this copyright and license, "Contributing Authors"
is defined as the following set of individuals: is defined as the following set of individuals:
Andreas Dilger Andreas Dilger
Dave Martindale Dave Martindale
Guy Eric Schalnat Guy Eric Schalnat
Paul Schmidt Paul Schmidt
Tim Wegner Tim Wegner
The PNG Reference Library is supplied "AS IS". The Contributing Authors The PNG Reference Library is supplied "AS IS". The Contributing
and Group 42, Inc. disclaim all warranties, expressed or implied, Authors and Group 42, Inc. disclaim all warranties, expressed or
including, without limitation, the warranties of merchantability and of implied, including, without limitation, the warranties of
fitness for any purpose. The Contributing Authors and Group 42, Inc. merchantability and of fitness for any purpose. The Contributing
assume no liability for direct, indirect, incidental, special, exemplary, Authors and Group 42, Inc. assume no liability for direct, indirect,
or consequential damages, which may result from the use of the PNG incidental, special, exemplary, or consequential damages, which may
Reference Library, even if advised of the possibility of such damage. 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 Permission is hereby granted to use, copy, modify, and distribute this
source code, or portions hereof, for any purpose, without fee, subject source code, or portions hereof, for any purpose, without fee, subject
to the following restrictions: to the following restrictions:
1. The origin of this source code must not be misrepresented. 1. The origin of this source code must not be misrepresented.
2. Altered versions must be plainly marked as such and must not 2. Altered versions must be plainly marked as such and must not
be misrepresented as being the original source. be misrepresented as being the original source.
3. This Copyright notice may not be removed or altered from any 3. This Copyright notice may not be removed or altered from any
source or altered source distribution. source or altered source distribution.
The Contributing Authors and Group 42, Inc. specifically permit, without The Contributing Authors and Group 42, Inc. specifically permit,
fee, and encourage the use of this source code as a component to without fee, and encourage the use of this source code as a component
supporting the PNG file format in commercial products. If you use this to supporting the PNG file format in commercial products. If you use
source code in a product, acknowledgment is not required but would be this source code in a product, acknowledgment is not required but would
appreciated. be appreciated.
END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
TRADEMARK:
The name "libpng" has not been registered by the Copyright owner
as a trademark in any jurisdiction. However, because libpng has
been distributed and maintained world-wide, continually since 1995,
the Copyright owner claims "common-law trademark protection" in any
jurisdiction where common-law trademark is recognized.
OSI CERTIFICATION:
Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
a certification mark of the Open Source Initiative. OSI has not addressed
the additional disclaimers inserted at version 1.0.7.
EXPORT CONTROL:
The Copyright owner believes that the Export Control Classification
Number (ECCN) for libpng is EAR99, which means not subject to export
controls or International Traffic in Arms Regulations (ITAR) because
it is open source, publicly available software, that does not contain
any encryption software. See the EAR, paragraphs 734.3(b)(3) and
734.7(b).
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
June 9, 2016

@ -1,15 +1,16 @@
README for libpng version 1.6.23 - June 9, 2016 (shared library 16.0) README for libpng version 1.6.37 - April 14, 2019
See the note about version numbers near the top of png.h =================================================
See the note about version numbers near the top of png.h.
See INSTALL for instructions on how to install libpng. See INSTALL for instructions on how to install libpng.
Libpng comes in several distribution formats. Get libpng-*.tar.gz or Libpng comes in several distribution formats. Get libpng-*.tar.gz or
libpng-*.tar.xz or if you want UNIX-style line endings in the text files, libpng-*.tar.xz or if you want UNIX-style line endings in the text
or lpng*.7z or lpng*.zip if you want DOS-style line endings. files, or lpng*.7z or lpng*.zip if you want DOS-style line endings.
Version 0.89 was the first official release of libpng. Don't let the Version 0.89 was the first official release of libpng. Don't let the
fact that it's the first release fool you. The libpng library has been in fact that it's the first release fool you. The libpng library has been
extensive use and testing since mid-1995. By late 1997 it had in extensive use and testing since mid-1995. By late 1997 it had
finally gotten to the stage where there hadn't been significant finally gotten to the stage where there hadn't been significant
changes to the API in some time, and people have a bad feeling about changes to the API in some time, and people have a bad feeling about
libraries with versions < 1.0. Version 1.0.0 was released in libraries with versions < 1.0. Version 1.0.0 was released in
@ -23,7 +24,7 @@ earlier versions if you are using a shared library. The type of the
png_uint_32, which will affect shared-library applications that use png_uint_32, which will affect shared-library applications that use
this function. this function.
To avoid problems with changes to the internals of png info_struct, To avoid problems with changes to the internals of the png info_struct,
new APIs have been made available in 0.95 to avoid direct application new APIs have been made available in 0.95 to avoid direct application
access to info_ptr. These functions are the png_set_<chunk> and access to info_ptr. These functions are the png_set_<chunk> and
png_get_<chunk> functions. These functions should be used when png_get_<chunk> functions. These functions should be used when
@ -60,94 +61,59 @@ the library action on the detection of chunk CRC errors. It is possible
to set different actions based on whether the CRC error occurred in a to set different actions based on whether the CRC error occurred in a
critical or an ancillary chunk. critical or an ancillary chunk.
The changes made to the library, and bugs fixed are based on discussions For a detailed description on using libpng, read libpng-manual.txt.
on the PNG-implement mailing list and not on material submitted For examples of libpng in a program, see example.c and pngtest.c. For
privately to Guy, Andreas, or Glenn. They will forward any good usage information and restrictions (what little they are) on libpng,
suggestions to the list. see png.h. For a description on using zlib (the compression library
used by libpng) and zlib's restrictions, see zlib.h
For a detailed description on using libpng, read libpng-manual.txt. For
examples of libpng in a program, see example.c and pngtest.c. For usage
information and restrictions (what little they are) on libpng, see
png.h. For a description on using zlib (the compression library used by
libpng) and zlib's restrictions, see zlib.h
I have included a general makefile, as well as several machine and I have included a general makefile, as well as several machine and
compiler specific ones, but you may have to modify one for your own needs. compiler specific ones, but you may have to modify one for your own
needs.
You should use zlib 1.0.4 or later to run this, but it MAY work with You should use zlib 1.0.4 or later to run this, but it MAY work with
versions as old as zlib 0.95. Even so, there are bugs in older zlib versions as old as zlib 0.95. Even so, there are bugs in older zlib
versions which can cause the output of invalid compression streams for versions which can cause the output of invalid compression streams for
some images. You will definitely need zlib 1.0.4 or later if you are some images.
taking advantage of the MS-DOS "far" structure allocation for the small
and medium memory models. You should also note that zlib is a
compression library that is useful for more things than just PNG files.
You can use zlib as a drop-in replacement for fread() and fwrite() if
you are so inclined.
zlib should be available at the same place that libpng is, or at zlib.net. You should also note that zlib is a compression library that is useful
for more things than just PNG files. You can use zlib as a drop-in
replacement for fread() and fwrite(), if you are so inclined.
zlib should be available at the same place that libpng is, or at
https://zlib.net.
You may also want a copy of the PNG specification. It is available You may also want a copy of the PNG specification. It is available
as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find
these at http://www.libpng.org/pub/png/documents/ these at http://www.libpng.org/pub/png/pngdocs.html .
This code is currently being archived at libpng.sf.net in the This code is currently being archived at libpng.sourceforge.io in the
[DOWNLOAD] area, and at ftp://ftp.simplesystems.org. If you can't find it [DOWNLOAD] area, and at http://libpng.download/src .
in any of those places, e-mail me, and I'll help you find it.
I am not a lawyer, but I believe that the Export Control Classification This release, based in a large way on Glenn's, Guy's and Andreas'
Number (ECCN) for libpng is EAR99, which means not subject to export earlier work, was created and will be supported by myself and the PNG
controls or International Traffic in Arms Regulations (ITAR) because it
is open source, publicly available software, that does not contain any
encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b).
If you have any code changes, requests, problems, etc., please e-mail
them to me. Also, I'd appreciate any make files or project files,
and any modifications you needed to make to get libpng to compile,
along with a #define variable to tell what compiler/system you are on.
If you needed to add transformations to libpng, or wish libpng would
provide the image in a different way, drop me a note (and code, if
possible), so I can consider supporting the transformation.
Finally, if you get any warning messages when compiling libpng
(note: not zlib), and they are easy to fix, I'd appreciate the
fix. Please mention "libpng" somewhere in the subject line. Thanks.
This release was created and will be supported by myself (of course
based in a large way on Guy's and Andreas' earlier work), and the PNG
development group. development group.
Send comments/corrections/commendations to png-mng-implement at Send comments/corrections/commendations to png-mng-implement at
lists.sourceforge.net (subscription required; visit lists.sourceforge.net (subscription required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement https://lists.sourceforge.net/lists/listinfo/png-mng-implement
to subscribe) or to glennrp at users.sourceforge.net to subscribe).
You can't reach Guy, the original libpng author, at the addresses Send general questions about the PNG specification to png-mng-misc
given in previous versions of this document. He and Andreas will at lists.sourceforge.net (subscription required; visit
read mail addressed to the png-implement list, however.
Please do not send general questions about PNG. Send them to
png-mng-misc at lists.sf.net (subscription required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-misc to https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
subscribe). If you have a question about something subscribe).
in the PNG specification that is related to using libpng, send it
to me. Send me any questions that start with "I was using libpng,
and ...". If in doubt, send questions to me. I'll bounce them
to others, if necessary.
Please do not send suggestions on how to change PNG. We have
been discussing PNG for twenty years now, and it is official and
finished. If you have suggestions for libpng, however, I'll
gladly listen. Even if your suggestion is not used immediately,
it may be used later.
Files in this distribution: Files in this distribution:
ANNOUNCE => Announcement of this version, with recent changes ANNOUNCE => Announcement of this version, with recent changes
AUTHORS => List of contributing authors
CHANGES => Description of changes between libpng versions CHANGES => Description of changes between libpng versions
KNOWNBUG => List of known bugs and deficiencies KNOWNBUG => List of known bugs and deficiencies
LICENSE => License to use and redistribute libpng LICENSE => License to use and redistribute libpng
README => This file README => This file
TODO => Things not implemented in the current library TODO => Things not implemented in the current library
Y2KINFO => Statement of Y2K compliance TRADEMARK => Trademark information
example.c => Example code for using libpng functions example.c => Example code for using libpng functions
libpng.3 => manual page for libpng (includes libpng-manual.txt) libpng.3 => manual page for libpng (includes libpng-manual.txt)
libpng-manual.txt => Description of libpng and its functions libpng-manual.txt => Description of libpng and its functions
@ -179,18 +145,25 @@ Files in this distribution:
pngwtran.c => Write data transformations pngwtran.c => Write data transformations
pngwutil.c => Write utility functions pngwutil.c => Write utility functions
arm => Contains optimized code for the ARM platform arm => Contains optimized code for the ARM platform
powerpc => Contains optimized code for the PowerPC platform
contrib => Contributions contrib => Contributions
arm-neon => Optimized code for ARM-NEON platform
powerpc-vsx => Optimized code for POWERPC-VSX platform
examples => Example programs examples => Example programs
gregbook => source code for PNG reading and writing, from gregbook => source code for PNG reading and writing, from
Greg Roelofs' "PNG: The Definitive Guide", Greg Roelofs' "PNG: The Definitive Guide",
O'Reilly, 1999 O'Reilly, 1999
libtests => Test programs libtests => Test programs
mips-msa => Optimized code for MIPS-MSA platform
pngminim => Minimal decoder, encoder, and progressive decoder pngminim => Minimal decoder, encoder, and progressive decoder
programs demonstrating use of pngusr.dfa programs demonstrating use of pngusr.dfa
pngminus => Simple pnm2png and png2pnm programs pngminus => Simple pnm2png and png2pnm programs
pngsuite => Test images pngsuite => Test images
testpngs
tools => Various tools tools => Various tools
visupng => Contains a MSVC workspace for VisualPng visupng => Contains a MSVC workspace for VisualPng
intel => Optimized code for INTEL-SSE2 platform
mips => Optimized code for MIPS platform
projects => Contains project files and workspaces for projects => Contains project files and workspaces for
building a DLL building a DLL
owatcom => Contains a WATCOM project for building libpng owatcom => Contains a WATCOM project for building libpng
@ -201,15 +174,10 @@ Files in this distribution:
scripts => Directory containing scripts for building libpng: scripts => Directory containing scripts for building libpng:
(see scripts/README.txt for the list of scripts) (see scripts/README.txt for the list of scripts)
Good luck, and happy coding. Good luck, and happy coding!
-Glenn Randers-Pehrson (current maintainer, since 1998) * Cosmin Truta (current maintainer, since 2018)
Internet: glennrp at users.sourceforge.net * Glenn Randers-Pehrson (former maintainer, 1998-2018)
* Andreas Eric Dilger (former maintainer, 1996-1997)
-Andreas Eric Dilger (former maintainer, 1996-1997) * Guy Eric Schalnat (original author and former maintainer, 1995-1996)
Internet: adilger at enel.ucalgary.ca (formerly of Group 42, Inc.)
Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
-Guy Eric Schalnat (original author and former maintainer, 1995-1996)
(formerly of Group 42, Inc)
Internet: gschal at infinet.com

@ -1,29 +1,23 @@
/*
TODO - list of things to do for libpng: TODO - list of things to do for libpng:
Final bug fixes. * Fix all defects (duh!)
Better C++ wrapper/full C++ implementation? * Better C++ wrapper / full C++ implementation (?)
Fix problem with C++ and EXTERN "C". * Fix the problems with C++ and 'extern "C"'.
cHRM transformation. * cHRM transformation.
Remove setjmp/longjmp usage in favor of returning error codes. * Palette creation.
Palette creation. * "grayscale->palette" transformation and "palette->grayscale" detection.
Add "grayscale->palette" transformation and "palette->grayscale" detection. * Improved dithering.
Improved dithering. * Multi-lingual error and warning message support.
Multi-lingual error and warning message support. * Complete sRGB transformation. (Currently it simply uses gamma=0.45455.)
Complete sRGB transformation (presently it simply uses gamma=0.45455). * Man pages for function calls.
Make profile checking optional via a png_set_something() call. * Better documentation.
Man pages for function calls. * Better filter selection
Better documentation. (e.g., counting huffman bits/precompression; filter inertia; filter costs).
Better filter selection * Histogram creation.
(counting huffman bits/precompression? filter inertia? filter costs?). * Text conversion between different code pages (e.g., Latin-1 -> Mac).
Histogram creation. * Avoid building gamma tables whenever possible.
Text conversion between different code pages (Latin-1 -> Mac and DOS). * Greater precision in changing to linear gamma for compositing against
Avoid building gamma tables whenever possible. background, and in doing rgb-to-gray transformations.
Use greater precision when changing to linear gamma for compositing against * Investigate pre-incremented loop counters and other loop constructions.
background and doing rgb-to-gray transformation. * Interpolated method of handling interlacing.
Investigate pre-incremented loop counters and other loop constructions. * More validations for libpng transformations.
Add interpolated method of handling interlacing.
Switch to the simpler zlib (zlib/libpng) license if legally possible.
Extend pngvalid.c to validate more of the libpng transformations.
*/

@ -0,0 +1,8 @@
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.

@ -1,19 +0,0 @@
echo "
There is no \"configure\" script in this distribution (*.zip or *.7z) of
libpng-1.6.23.
Instead, please copy the appropriate makefile for your system from the
\"scripts\" directory. Read the INSTALL file for more details.
Update, July 2004: you can get a \"configure\" based distribution
from the libpng distribution sites. Download the file
libpng-1.6.23.tar.gz or libpng-1.6.23.tar.xz.
If the line endings in the files look funny, which is likely to be the
case if you were trying to run \"configure\" on a Linux machine, you may
wish to get the other distribution of libpng. It is available in both
tar.gz/tar.xz (UNIX style line endings, with \"configure\") and .7z/.zip
(DOS style line endings, without \"configure\") formats.
"

File diff suppressed because it is too large Load Diff

@ -1,127 +0,0 @@
#! /bin/sh
# libpng-config
# provides configuration info for libpng.
# Copyright (C) 2002, 2004, 2006, 2007 Glenn Randers-Pehrson
# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
# and license in png.h
# Modeled after libxml-config.
version="@PNGLIB_VERSION@"
prefix="@prefix@"
exec_prefix="@exec_prefix@"
libdir="@libdir@"
includedir="@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@"
libs="-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@"
all_libs="-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ @LIBS@"
I_opts="-I${includedir}"
L_opts="-L${libdir}"
R_opts=""
cppflags=""
ccopts=""
ldopts=""
usage()
{
cat <<EOF
Usage: $0 [OPTION] ...
Known values for OPTION are:
--prefix print libpng prefix
--libdir print path to directory containing library
--libs print library linking information
--ccopts print compiler options
--cppflags print pre-processor flags
--cflags print preprocessor flags, I_opts, and compiler options
--I_opts print "-I" include options
--L_opts print linker "-L" flags for dynamic linking
--R_opts print dynamic linker "-R" or "-rpath" flags
--ldopts print linker options
--ldflags print linker flags (ldopts, L_opts, R_opts, and libs)
--static revise subsequent outputs for static linking
--help print this help and exit
--version print version information
EOF
exit $1
}
if test $# -eq 0; then
usage 1
fi
while test $# -gt 0; do
case "$1" in
--prefix)
echo ${prefix}
;;
--version)
echo ${version}
exit 0
;;
--help)
usage 0
;;
--ccopts)
echo ${ccopts}
;;
--cppflags)
echo ${cppflags}
;;
--cflags)
echo ${I_opts} ${cppflags} ${ccopts}
;;
--libdir)
echo ${libdir}
;;
--libs)
echo ${libs}
;;
--I_opts)
echo ${I_opts}
;;
--L_opts)
echo ${L_opts}
;;
--R_opts)
echo ${R_opts}
;;
--ldopts)
echo ${ldopts}
;;
--ldflags)
echo ${ldopts} ${L_opts} ${R_opts} ${libs}
;;
--static)
R_opts=""
libs=${all_libs}
;;
*)
usage
exit 1
;;
esac
shift
done
exit 0

@ -1,9 +1,7 @@
libpng-manual.txt - A description on how to use and modify libpng libpng-manual.txt - A description on how to use and modify libpng
libpng version 1.6.23 - June 9, 2016 Copyright (c) 2018-2019 Cosmin Truta
Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2018 Glenn Randers-Pehrson
<glennrp at users.sourceforge.net>
Copyright (c) 1998-2016 Glenn Randers-Pehrson
This document is released under the libpng license. This document is released under the libpng license.
For conditions of distribution and use, see the disclaimer For conditions of distribution and use, see the disclaimer
@ -11,9 +9,13 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on: Based on:
libpng versions 0.97, January 1998, through 1.6.23 - June 9, 2016 libpng version 1.6.36, December 2018, through 1.6.37 - April 2019
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2019 Cosmin Truta
libpng versions 0.97, January 1998, through 1.6.35 - July 2018
Updated and distributed by Glenn Randers-Pehrson Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2016 Glenn Randers-Pehrson Copyright (c) 1998-2018 Glenn Randers-Pehrson
libpng 1.0 beta 6 - version 0.96 - May 28, 1997 libpng 1.0 beta 6 - version 0.96 - May 28, 1997
Updated and distributed by Andreas Dilger Updated and distributed by Andreas Dilger
@ -45,7 +47,6 @@ libpng-manual.txt - A description on how to use and modify libpng
XIII. Detecting libpng XIII. Detecting libpng
XIV. Source code repository XIV. Source code repository
XV. Coding style XV. Coding style
XVI. Y2K Compliance in libpng
I. Introduction I. Introduction
@ -66,17 +67,17 @@ file format in application programs.
The PNG specification (second edition), November 2003, is available as The PNG specification (second edition), November 2003, is available as
a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
<http://www.w3.org/TR/2003/REC-PNG-20031110/ <https://www.w3.org/TR/2003/REC-PNG-20031110/>.
The W3C and ISO documents have identical technical content. The W3C and ISO documents have identical technical content.
The PNG-1.2 specification is available at The PNG-1.2 specification is available at
<http://png-mng.sourceforge.net/pub/png/spec/1.2/>. <https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
It is technically equivalent It is technically equivalent
to the PNG specification (second edition) but has some additional material. to the PNG specification (second edition) but has some additional material.
The PNG-1.0 specification is available as RFC 2083 The PNG-1.0 specification is available as RFC 2083 at
<http://png-mng.sourceforge.net/pub/png/spec/1.0/> and as a <https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
W3C Recommendation <http://www.w3.org/TR/REC-png-961001>. W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
Some additional chunks are described in the special-purpose public chunks Some additional chunks are described in the special-purpose public chunks
documents at <http://www.libpng.org/pub/png/spec/register/> documents at <http://www.libpng.org/pub/png/spec/register/>
@ -101,7 +102,7 @@ majority of the needs of its users.
Libpng uses zlib for its compression and decompression of PNG files. Libpng uses zlib for its compression and decompression of PNG files.
Further information about zlib, and the latest version of zlib, can Further information about zlib, and the latest version of zlib, can
be found at the zlib home page, <http://zlib.net/>. be found at the zlib home page, <https://zlib.net/>.
The zlib compression utility is a general purpose utility that is The zlib compression utility is a general purpose utility that is
useful for more than PNG files, and can be used without libpng. useful for more than PNG files, and can be used without libpng.
See the documentation delivered with zlib for more details. See the documentation delivered with zlib for more details.
@ -348,18 +349,18 @@ Customizing libpng.
FILE *fp = fopen(file_name, "rb"); FILE *fp = fopen(file_name, "rb");
if (!fp) if (!fp)
{ {
return (ERROR); return ERROR;
} }
if (fread(header, 1, number, fp) != number) if (fread(header, 1, number, fp) != number)
{ {
return (ERROR); return ERROR;
} }
is_png = !png_sig_cmp(header, 0, number); is_png = !png_sig_cmp(header, 0, number);
if (!is_png) if (!is_png)
{ {
return (NOT_PNG); return NOT_PNG;
} }
Next, png_struct and png_info need to be allocated and initialized. In Next, png_struct and png_info need to be allocated and initialized. In
@ -378,7 +379,7 @@ create the structure, so your application should check for that.
user_error_fn, user_warning_fn); user_error_fn, user_warning_fn);
if (!png_ptr) if (!png_ptr)
return (ERROR); return ERROR;
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
@ -386,7 +387,7 @@ create the structure, so your application should check for that.
{ {
png_destroy_read_struct(&png_ptr, png_destroy_read_struct(&png_ptr,
(png_infopp)NULL, (png_infopp)NULL); (png_infopp)NULL, (png_infopp)NULL);
return (ERROR); return ERROR;
} }
If you want to use your own memory allocation routines, If you want to use your own memory allocation routines,
@ -421,7 +422,7 @@ free any memory.
png_destroy_read_struct(&png_ptr, &info_ptr, png_destroy_read_struct(&png_ptr, &info_ptr,
&end_info); &end_info);
fclose(fp); fclose(fp);
return (ERROR); return ERROR;
} }
Pass (png_infopp)NULL instead of &end_info if you didn't create Pass (png_infopp)NULL instead of &end_info if you didn't create
@ -467,8 +468,9 @@ the default, use
The values for png_set_crc_action() say how libpng is to handle CRC errors in The values for png_set_crc_action() say how libpng is to handle CRC errors in
ancillary and critical chunks, and whether to use the data contained ancillary and critical chunks, and whether to use the data contained
therein. Note that it is impossible to "discard" data in a critical therein. Starting with libpng-1.6.26, this also governs how an ADLER32 error
chunk. is handled while reading the IDAT chunk. Note that it is impossible to
"discard" data in a critical chunk.
Choices for (int) crit_action are Choices for (int) crit_action are
PNG_CRC_DEFAULT 0 error/quit PNG_CRC_DEFAULT 0 error/quit
@ -485,6 +487,9 @@ Choices for (int) ancil_action are
PNG_CRC_QUIET_USE 4 quiet/use data PNG_CRC_QUIET_USE 4 quiet/use data
PNG_CRC_NO_CHANGE 5 use the current value PNG_CRC_NO_CHANGE 5 use the current value
When the setting for crit_action is PNG_CRC_QUIET_USE, the CRC and ADLER32
checksums are not only ignored, but they are not evaluated.
Setting up callback code Setting up callback code
You can set up a callback function to handle any unknown chunks in the You can set up a callback function to handle any unknown chunks in the
@ -499,7 +504,7 @@ input stream. You must supply the function
png_byte name[5]; png_byte name[5];
png_byte *data; png_byte *data;
png_size_t size; size_t size;
/* Note that libpng has already taken care of /* Note that libpng has already taken care of
the CRC handling */ the CRC handling */
@ -508,9 +513,9 @@ input stream. You must supply the function
unknown chunk structure, process it, and return one unknown chunk structure, process it, and return one
of the following: */ of the following: */
return (-n); /* chunk had an error */ return -n; /* chunk had an error */
return (0); /* did not recognize */ return 0; /* did not recognize */
return (n); /* success */ return n; /* success */
} }
(You can give your function another name that you like instead of (You can give your function another name that you like instead of
@ -559,7 +564,7 @@ non-interlaced case the row that was just handled is simply one less than the
passed in row number, and pass will always be 0. For the interlaced case the passed in row number, and pass will always be 0. For the interlaced case the
same applies unless the row value is 0, in which case the row just handled was same applies unless the row value is 0, in which case the row just handled was
the last one from one of the preceding passes. Because interlacing may skip a the last one from one of the preceding passes. Because interlacing may skip a
pass you cannot be sure that the preceding pass is just 'pass-1', if you really pass you cannot be sure that the preceding pass is just 'pass-1'; if you really
need to know what the last pass is record (row,pass) from the callback and use need to know what the last pass is record (row,pass) from the callback and use
the last recorded value each time. the last recorded value each time.
@ -684,8 +689,9 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with
chunk_cache_max = png_get_chunk_cache_max(png_ptr); chunk_cache_max = png_get_chunk_cache_max(png_ptr);
Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of
memory that a compressed chunk other than IDAT can occupy, when decompressed. memory that any chunk other than IDAT can occupy, originally or when
You can change this limit with decompressed (prior to libpng-1.6.32 the limit was only applied to compressed
chunks after decompression). You can change this limit with
png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max); png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
@ -981,15 +987,24 @@ premultiplication.
png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
This is the default libpng handling of the alpha channel - it is not Choices for the alpha_mode are
pre-multiplied into the color components. In addition the call states
PNG_ALPHA_PNG 0 /* according to the PNG standard */
PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */
PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */
PNG_ALPHA_PREMULTIPLIED 1 /* as above */
PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */
PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */
PNG_ALPHA_PNG is the default libpng handling of the alpha channel. It is not
pre-multiplied into the color components. In addition the call states
that the output is for a sRGB system and causes all PNG files without gAMA that the output is for a sRGB system and causes all PNG files without gAMA
chunks to be assumed to be encoded using sRGB. chunks to be assumed to be encoded using sRGB.
png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); 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 In this case the output is assumed to be something like an sRGB conformant
display preceeded by a power-law lookup table of power 1.45. This is how display preceded by a power-law lookup table of power 1.45. This is how
early Mac systems behaved. early Mac systems behaved.
png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@ -997,7 +1012,7 @@ early Mac systems behaved.
This is the classic Jim Blinn approach and will work in academic This is the classic Jim Blinn approach and will work in academic
environments where everything is done by the book. It has the shortcoming environments where everything is done by the book. It has the shortcoming
of assuming that input PNG data with no gamma information is linear - this of assuming that input PNG data with no gamma information is linear - this
is unlikely to be correct unless the PNG files where generated locally. is unlikely to be correct unless the PNG files were generated locally.
Most of the time the output precision will be so low as to show Most of the time the output precision will be so low as to show
significant banding in dark areas of the image. significant banding in dark areas of the image.
@ -1041,7 +1056,7 @@ faster.)
When the default gamma of PNG files doesn't match the output gamma. 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 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 ouput gamma to the you to provide a default gamma, but it also sets the output gamma to the
matching value. If you know your PNG files have a gamma that doesn't 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 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 png_set_alpha_mode always sets the output gamma but only sets the PNG
@ -1186,7 +1201,20 @@ row_pointers prior to calling png_read_png() with
png_set_rows(png_ptr, info_ptr, &row_pointers); png_set_rows(png_ptr, info_ptr, &row_pointers);
Alternatively you could allocate your image in one big block and define Alternatively you could allocate your image in one big block and define
row_pointers[i] to point into the proper places in your block. row_pointers[i] to point into the proper places in your block, but first
be sure that your platform is able to allocate such a large buffer:
/* Guard against integer overflow */
if (height > PNG_SIZE_MAX/(width*pixel_size)) {
png_error(png_ptr,"image_data buffer would be too large");
}
png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
for (int i=0; i<height, i++)
row_pointers[i]=buffer+i*width*pixel_size;
png_set_rows(png_ptr, info_ptr, &row_pointers);
If you use png_set_rows(), the application is responsible for freeing If you use png_set_rows(), the application is responsible for freeing
row_pointers (and row_pointers[i], if they were separately allocated). row_pointers (and row_pointers[i], if they were separately allocated).
@ -1313,6 +1341,11 @@ in until png_read_end() has read the chunk data following the image.
rowbytes = png_get_rowbytes(png_ptr, info_ptr); rowbytes = png_get_rowbytes(png_ptr, info_ptr);
rowbytes - number of bytes needed to hold a row rowbytes - number of bytes needed to hold a row
This value, the bit_depth, color_type,
and the number of channels can change
if you use transforms such as
png_set_expand(). See
png_read_update_info(), below.
signature = png_get_signature(png_ptr, info_ptr); signature = png_get_signature(png_ptr, info_ptr);
@ -1431,6 +1464,11 @@ png_set_rgb_to_gray()).
the single transparent color for the single transparent color for
non-paletted images (PNG_INFO_tRNS) non-paletted images (PNG_INFO_tRNS)
png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif);
(PNG_INFO_eXIf)
exif - Exif profile (array of png_byte)
png_get_hIST(png_ptr, info_ptr, &hist); png_get_hIST(png_ptr, info_ptr, &hist);
(PNG_INFO_hIST) (PNG_INFO_hIST)
@ -2142,6 +2180,16 @@ are allocating one large chunk, you will need to build an
array of pointers to each row, as it will be needed for some array of pointers to each row, as it will be needed for some
of the functions below. of the functions below.
Be sure that your platform can allocate the buffer that you'll need.
libpng internally checks for oversize width, but you'll need to
do your own check for number_of_rows*width*pixel_size if you are using
a multiple-row buffer:
/* Guard against integer overflow */
if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
png_error(png_ptr,"image_data buffer would be too large");
}
Remember: Before you call png_read_update_info(), the png_get_*() Remember: Before you call png_read_update_info(), the png_get_*()
functions return the values corresponding to the original PNG image. functions return the values corresponding to the original PNG image.
After you call png_read_update_info the values refer to the image After you call png_read_update_info the values refer to the image
@ -2230,7 +2278,8 @@ is exactly the same. If you are planning on displaying the image
after each pass, the "rectangle" effect is generally considered the after each pass, the "rectangle" effect is generally considered the
better looking one. better looking one.
If you only want the "sparkle" effect, just call png_read_rows() as If you only want the "sparkle" effect, just call png_read_row() or
png_read_rows() as
normal, with the third parameter NULL. Make sure you make pass over normal, with the third parameter NULL. Make sure you make pass over
the image number_of_passes times, and you don't change the data in the the image number_of_passes times, and you don't change the data in the
rows between calls. You can change the locations of the data, just rows between calls. You can change the locations of the data, just
@ -2239,6 +2288,8 @@ pass, and assumes the data from previous passes is still valid.
png_read_rows(png_ptr, row_pointers, NULL, png_read_rows(png_ptr, row_pointers, NULL,
number_of_rows); number_of_rows);
or
png_read_row(png_ptr, row_pointers, NULL);
If you only want the first effect (the rectangles), do the same as If you only want the first effect (the rectangles), do the same as
before except pass the row buffer in the third parameter, and leave before except pass the row buffer in the third parameter, and leave
@ -2246,6 +2297,8 @@ the second parameter NULL.
png_read_rows(png_ptr, NULL, row_pointers, png_read_rows(png_ptr, NULL, row_pointers,
number_of_rows); number_of_rows);
or
png_read_row(png_ptr, NULL, row_pointers);
If you don't want libpng to handle the interlacing details, just call If you don't want libpng to handle the interlacing details, just call
png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images. png_read_rows() PNG_INTERLACE_ADAM7_PASSES times to read in all the images.
@ -2357,7 +2410,7 @@ separate.
{ {
png_destroy_read_struct(&png_ptr, &info_ptr, png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL); (png_infopp)NULL);
return (ERROR); return ERROR;
} }
png_read_end(png_ptr, end_info); png_read_end(png_ptr, end_info);
@ -2461,6 +2514,7 @@ your application instead of by libpng, you can use
PNG_INFO_gAMA, PNG_INFO_sBIT, PNG_INFO_gAMA, PNG_INFO_sBIT,
PNG_INFO_cHRM, PNG_INFO_PLTE, PNG_INFO_cHRM, PNG_INFO_PLTE,
PNG_INFO_tRNS, PNG_INFO_bKGD, PNG_INFO_tRNS, PNG_INFO_bKGD,
PNG_INFO_eXIf,
PNG_INFO_hIST, PNG_INFO_pHYs, PNG_INFO_hIST, PNG_INFO_pHYs,
PNG_INFO_oFFs, PNG_INFO_tIME, PNG_INFO_oFFs, PNG_INFO_tIME,
PNG_INFO_pCAL, PNG_INFO_sRGB, PNG_INFO_pCAL, PNG_INFO_sRGB,
@ -2496,7 +2550,7 @@ png_infop info_ptr;
user_error_fn, user_warning_fn); user_error_fn, user_warning_fn);
if (!png_ptr) if (!png_ptr)
return (ERROR); return ERROR;
info_ptr = png_create_info_struct(png_ptr); info_ptr = png_create_info_struct(png_ptr);
@ -2504,14 +2558,14 @@ png_infop info_ptr;
{ {
png_destroy_read_struct(&png_ptr, png_destroy_read_struct(&png_ptr,
(png_infopp)NULL, (png_infopp)NULL); (png_infopp)NULL, (png_infopp)NULL);
return (ERROR); return ERROR;
} }
if (setjmp(png_jmpbuf(png_ptr))) if (setjmp(png_jmpbuf(png_ptr)))
{ {
png_destroy_read_struct(&png_ptr, &info_ptr, png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL); (png_infopp)NULL);
return (ERROR); return ERROR;
} }
/* This one's new. You can provide functions /* This one's new. You can provide functions
@ -2545,7 +2599,7 @@ png_infop info_ptr;
{ {
png_destroy_read_struct(&png_ptr, &info_ptr, png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL); (png_infopp)NULL);
return (ERROR); return ERROR;
} }
/* This one's new also. Simply give it a chunk /* This one's new also. Simply give it a chunk
@ -2689,7 +2743,7 @@ custom writing functions. See the discussion under Customizing libpng.
FILE *fp = fopen(file_name, "wb"); FILE *fp = fopen(file_name, "wb");
if (!fp) if (!fp)
return (ERROR); return ERROR;
Next, png_struct and png_info need to be allocated and initialized. Next, png_struct and png_info need to be allocated and initialized.
As these can be both relatively large, you may not want to store these As these can be both relatively large, you may not want to store these
@ -2704,14 +2758,14 @@ both "png_ptr"; you can call them anything you like, such as
user_error_fn, user_warning_fn); user_error_fn, user_warning_fn);
if (!png_ptr) if (!png_ptr)
return (ERROR); return ERROR;
png_infop info_ptr = png_create_info_struct(png_ptr); png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) if (!info_ptr)
{ {
png_destroy_write_struct(&png_ptr, png_destroy_write_struct(&png_ptr,
(png_infopp)NULL); (png_infopp)NULL);
return (ERROR); return ERROR;
} }
If you want to use your own memory allocation routines, If you want to use your own memory allocation routines,
@ -2738,7 +2792,7 @@ section below for more information on the libpng error handling.
{ {
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp); fclose(fp);
return (ERROR); return ERROR;
} }
... ...
return; return;
@ -3060,6 +3114,11 @@ width, height, bit_depth, and color_type must be the same in each call.
single transparent color for single transparent color for
non-paletted images (PNG_INFO_tRNS) non-paletted images (PNG_INFO_tRNS)
png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif);
exif - Exif profile (array of
png_byte) (PNG_INFO_eXIf)
png_set_hIST(png_ptr, info_ptr, hist); png_set_hIST(png_ptr, info_ptr, hist);
hist - histogram of palette (array of hist - histogram of palette (array of
@ -3721,7 +3780,7 @@ 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 accommodate your needs then you can, and should, use the more
sophisticated APIs above - these support a wide variety of in-memory formats sophisticated APIs above - these support a wide variety of in-memory formats
and a wide variety of sophisticated transformations to those formats as well and a wide variety of sophisticated transformations to those formats as well
as a wide variety of APIs to manipulate ancilliary information. as a wide variety of APIs to manipulate ancillary information.
To read a PNG file using the simplified API: To read a PNG file using the simplified API:
@ -3815,7 +3874,7 @@ PNG_FORMAT_FLAG_LINEAR flag below.
When the simplified API needs to convert between sRGB and linear colorspaces, When the simplified API needs to convert between sRGB and linear colorspaces,
the actual sRGB transfer curve defined in the sRGB specification (see the the actual sRGB transfer curve defined in the sRGB specification (see the
article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
approximation used elsewhere in libpng. approximation used elsewhere in libpng.
When an alpha channel is present it is expected to denote pixel coverage When an alpha channel is present it is expected to denote pixel coverage
@ -3997,7 +4056,7 @@ Flags containing additional information about the image are held in
the 'flags' field of png_image. the 'flags' field of png_image.
PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01 PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01
This indicates the the RGB values of the in-memory bitmap do not This indicates that the RGB values of the in-memory bitmap do not
correspond to the red, green and blue end-points defined by sRGB. correspond to the red, green and blue end-points defined by sRGB.
PNG_IMAGE_FLAG_FAST == 0x02 PNG_IMAGE_FLAG_FAST == 0x02
@ -4044,7 +4103,7 @@ READ APIs
The PNG header is read from the stdio FILE object. The PNG header is read from the stdio FILE object.
int png_image_begin_read_from_memory(png_imagep image, int png_image_begin_read_from_memory(png_imagep image,
png_const_voidp memory, png_size_t size) png_const_voidp memory, size_t size)
The PNG header is read from the given memory buffer. The PNG header is read from the given memory buffer.
@ -4079,7 +4138,7 @@ READ APIs
When the simplified API needs to convert between sRGB and linear colorspaces, When the simplified API needs to convert between sRGB and linear colorspaces,
the actual sRGB transfer curve defined in the sRGB specification (see the the actual sRGB transfer curve defined in the sRGB specification (see the
article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
approximation used elsewhere in libpng. approximation used elsewhere in libpng.
WRITE APIS WRITE APIS
@ -4197,10 +4256,10 @@ png_get_io_ptr(). For example:
The replacement I/O functions must have prototypes as follows: The replacement I/O functions must have prototypes as follows:
void user_read_data(png_structp png_ptr, void user_read_data(png_structp png_ptr,
png_bytep data, png_size_t length); png_bytep data, size_t length);
void user_write_data(png_structp png_ptr, void user_write_data(png_structp png_ptr,
png_bytep data, png_size_t length); png_bytep data, size_t length);
void user_flush_data(png_structp png_ptr); void user_flush_data(png_structp png_ptr);
@ -4237,8 +4296,6 @@ functions after png_create_*_struct() has been called by calling:
png_voidp error_ptr, png_error_ptr error_fn, png_voidp error_ptr, png_error_ptr error_fn,
png_error_ptr warning_fn); png_error_ptr warning_fn);
png_voidp error_ptr = png_get_error_ptr(png_ptr);
If NULL is supplied for either error_fn or warning_fn, then the libpng If NULL is supplied for either error_fn or warning_fn, then the libpng
default function will be used, calling fprintf() and/or longjmp() if a default function will be used, calling fprintf() and/or longjmp() if a
problem is encountered. The replacement error functions should have problem is encountered. The replacement error functions should have
@ -4250,6 +4307,11 @@ parameters as follows:
void user_warning_fn(png_structp png_ptr, void user_warning_fn(png_structp png_ptr,
png_const_charp warning_msg); png_const_charp warning_msg);
Then, within your user_error_fn or user_warning_fn, you can retrieve
the error_ptr if you need it, by calling
png_voidp error_ptr = png_get_error_ptr(png_ptr);
The motivation behind using setjmp() and longjmp() is the C++ throw and The motivation behind using setjmp() and longjmp() is the C++ throw and
catch exception handling methods. This makes the code much easier to write, catch exception handling methods. This makes the code much easier to write,
as there is no need to check every return code of every function call. as there is no need to check every return code of every function call.
@ -4257,7 +4319,7 @@ However, there are some uncertainties about the status of local variables
after a longjmp, so the user may want to be careful about doing anything after a longjmp, so the user may want to be careful about doing anything
after setjmp returns non-zero besides returning itself. Consult your after setjmp returns non-zero besides returning itself. Consult your
compiler documentation for more details. For an alternative approach, you compiler documentation for more details. For an alternative approach, you
may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net), may wish to use the "cexcept" facility (see https://cexcept.sourceforge.io/),
which is illustrated in pngvalid.c and in contrib/visupng. which is illustrated in pngvalid.c and in contrib/visupng.
Beginning in libpng-1.4.0, the png_set_benign_errors() API became available. Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
@ -4460,7 +4522,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
having level = 0 will be printed. There aren't any such statements in having level = 0 will be printed. There aren't any such statements in
this version of libpng, but if you insert some they will be printed. this version of libpng, but if you insert some they will be printed.
VII. MNG support VII. MNG support
The MNG specification (available at http://www.libpng.org/pub/mng) allows The MNG specification (available at http://www.libpng.org/pub/mng) allows
certain extensions to PNG for PNG images that are embedded in MNG datastreams. certain extensions to PNG for PNG images that are embedded in MNG datastreams.
@ -4485,9 +4547,9 @@ in a MNG datastream. As a minimum, it must have the MNG 8-byte signature
and the MHDR and MEND chunks. Libpng does not provide support for these and the MHDR and MEND chunks. Libpng does not provide support for these
or any other MNG chunks; your application must provide its own support for or any other MNG chunks; your application must provide its own support for
them. You may wish to consider using libmng (available at them. You may wish to consider using libmng (available at
http://www.libmng.com) instead. https://www.libmng.com/) instead.
VIII. Changes to Libpng from version 0.88 VIII. Changes to Libpng from version 0.88
It should be noted that versions of libpng later than 0.96 are not It should be noted that versions of libpng later than 0.96 are not
distributed by the original libpng author, Guy Schalnat, nor by distributed by the original libpng author, Guy Schalnat, nor by
@ -4542,7 +4604,7 @@ application:
png_uint_32 application_vn = PNG_LIBPNG_VER; png_uint_32 application_vn = PNG_LIBPNG_VER;
IX. Changes to Libpng from version 1.0.x to 1.2.x IX. Changes to Libpng from version 1.0.x to 1.2.x
Support for user memory management was enabled by default. To Support for user memory management was enabled by default. To
accomplish this, the functions png_create_read_struct_2(), accomplish this, the functions png_create_read_struct_2(),
@ -4639,7 +4701,7 @@ which also expands tRNS to alpha was replaced with
png_set_expand_gray_1_2_4_to_8() png_set_expand_gray_1_2_4_to_8()
which does not. It has been deprecated since libpng-1.0.18 and 1.2.9. which does not. It has been deprecated since libpng-1.0.18 and 1.2.9.
X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x
Private libpng prototypes and macro definitions were moved from Private libpng prototypes and macro definitions were moved from
png.h and pngconf.h into a new pngpriv.h header file. png.h and pngconf.h into a new pngpriv.h header file.
@ -4723,7 +4785,7 @@ behavior in case the application runs out of memory part-way through
the process. the process.
We changed the prototypes of png_get_compression_buffer_size() and We changed the prototypes of png_get_compression_buffer_size() and
png_set_compression_buffer_size() to work with png_size_t instead of png_set_compression_buffer_size() to work with size_t instead of
png_uint_32. png_uint_32.
Support for numbered error messages was removed by default, since we Support for numbered error messages was removed by default, since we
@ -4749,7 +4811,7 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED.
We removed the trailing '.' from the warning and error messages. We removed the trailing '.' from the warning and error messages.
XI. Changes to Libpng from version 1.4.x to 1.5.x XI. Changes to Libpng from version 1.4.x to 1.5.x
From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the 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. function) incorrectly returned a value of type png_uint_32.
@ -4812,7 +4874,7 @@ to png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep.
There are changes of form in png.h, including new and changed macros to There are changes of form in png.h, including new and changed macros to
declare parts of the API. Some API functions with arguments that are declare parts of the API. Some API functions with arguments that are
pointers to data not modified within the function have been corrected to pointers to data not modified within the function have been corrected to
declare these arguments with PNG_CONST. declare these arguments with const.
Much of the internal use of C macros to control the library build has also Much of the internal use of C macros to control the library build has also
changed and some of this is visible in the exported header files, in changed and some of this is visible in the exported header files, in
@ -4908,18 +4970,14 @@ PNG_USER_WIDTH_MAX and PNG_USER_HEIGHT_MAX, although this document said
that it could be used to override them. Now this function will reduce or that it could be used to override them. Now this function will reduce or
increase the limits. increase the limits.
Starting in libpng-1.5.10, the user limits can be set en masse with the Starting in libpng-1.5.22, default user limits were established. These
configuration option PNG_SAFE_LIMITS_SUPPORTED. If this option is enabled, can be overridden by application calls to png_set_user_limits(),
a set of "safe" limits is applied in pngpriv.h. These can be overridden by png_set_user_chunk_cache_max(), and/or png_set_user_malloc_max().
application calls to png_set_user_limits(), png_set_user_chunk_cache_max(), The limits are now
and/or png_set_user_malloc_max() that increase or decrease the limits. Also, max possible default
in libpng-1.5.10 the default width and height limits were increased
from 1,000,000 to 0x7fffffff (i.e., made unlimited). Therefore, the
limits are now
default safe
png_user_width_max 0x7fffffff 1,000,000 png_user_width_max 0x7fffffff 1,000,000
png_user_height_max 0x7fffffff 1,000,000 png_user_height_max 0x7fffffff 1,000,000
png_user_chunk_cache_max 0 (unlimited) 128 png_user_chunk_cache_max 0 (unlimited) 1000
png_user_chunk_malloc_max 0 (unlimited) 8,000,000 png_user_chunk_malloc_max 0 (unlimited) 8,000,000
The png_set_option() function (and the "options" member of the png struct) was The png_set_option() function (and the "options" member of the png struct) was
@ -5011,7 +5069,7 @@ even though the default is to use the macros - this allows applications
to choose at app buildtime whether or not to use macros (previously to choose at app buildtime whether or not to use macros (previously
impossible because the functions weren't in the default build.) impossible because the functions weren't in the default build.)
XII. Changes to Libpng from version 1.5.x to 1.6.x XII. Changes to Libpng from version 1.5.x to 1.6.x
A "simplified API" has been added (see documentation in png.h and a simple A "simplified API" has been added (see documentation in png.h and a simple
example in contrib/examples/pngtopng.c). The new publicly visible API example in contrib/examples/pngtopng.c). The new publicly visible API
@ -5169,7 +5227,12 @@ is an error. Previously this requirement of the PNG specification was not
enforced, and the palette was always limited to 256 entries. An over-length enforced, and the palette was always limited to 256 entries. An over-length
PLTE chunk found in an input PNG is silently truncated. PLTE chunk found in an input PNG is silently truncated.
XIII. Detecting libpng Starting with libpng-1.6.31, the eXIf chunk is supported. Libpng does not
attempt to decode the Exif profile; it simply returns a byte array
containing the profile to the calling application which must do its own
decoding.
XIII. Detecting libpng
The png_get_io_ptr() function has been present since libpng-0.88, has never The png_get_io_ptr() function has been present since libpng-0.88, has never
changed, and is unaffected by conditional compilation macros. It is the changed, and is unaffected by conditional compilation macros. It is the
@ -5185,27 +5248,32 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files
going back to version 0.70. You can access the git repository (read only) going back to version 0.70. You can access the git repository (read only)
at at
git://git.code.sf.net/p/libpng/code https://github.com/glennrp/libpng or
https://git.code.sf.net/p/libpng/code.git
or you can browse it with a web browser by selecting the "code" button at or you can browse it with a web browser at
https://sourceforge.net/projects/libpng https://github.com/glennrp/libpng or
https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
Patches can be sent to glennrp at users.sourceforge.net or to Patches can be sent to png-mng-implement at lists.sourceforge.net or
png-mng-implement at lists.sourceforge.net or you can upload them to uploaded to the libpng bug tracker at
the libpng bug tracker at
http://libpng.sourceforge.net https://libpng.sourceforge.io/
or as a "pull request" to
https://github.com/glennrp/libpng/pulls
We also accept patches built from the tar or zip distributions, and We also accept patches built from the tar or zip distributions, and
simple verbal discriptions of bug fixes, reported either to the simple verbal descriptions of bug fixes, reported either to the
SourceForge bug tracker, to the png-mng-implement at lists.sf.net SourceForge bug tracker, to the png-mng-implement at lists.sf.net
mailing list, or directly to glennrp. mailing list, as github issues.
XV. Coding style XV. Coding style
Our coding style is similar to the "Allman" style Our coding style is similar to the "Allman" style
(See http://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly (See https://en.wikipedia.org/wiki/Indent_style#Allman_style), with curly
braces on separate lines: braces on separate lines:
if (condition) if (condition)
@ -5221,7 +5289,7 @@ braces on separate lines:
The braces can be omitted from simple one-line actions: The braces can be omitted from simple one-line actions:
if (condition) if (condition)
return (0); return 0;
We use 3-space indentation, except for continued statements which We use 3-space indentation, except for continued statements which
are usually indented the same as the first line of the statement are usually indented the same as the first line of the statement
@ -5306,7 +5374,7 @@ Prior to libpng-1.6.0 we used a "png_sizeof()" macro, formatted as
though it were a function. though it were a function.
Control keywords if, for, while, and switch are always followed by a space Control keywords if, for, while, and switch are always followed by a space
to distinguish them from function calls, which have no trailing space. to distinguish them from function calls, which have no trailing space.
We put a space after each comma and after each semicolon We put a space after each comma and after each semicolon
in "for" statements, and we put spaces before and after each in "for" statements, and we put spaces before and after each
@ -5330,66 +5398,12 @@ with an even number of lower-case hex digits, and to make them unsigned
We prefer to use underscores rather than camelCase in names, except We prefer to use underscores rather than camelCase in names, except
for a few type names that we inherit from zlib.h. for a few type names that we inherit from zlib.h.
We prefer "if (something != 0)" and "if (something == 0)" We prefer "if (something != 0)" and "if (something == 0)" over
over "if (something)" and if "(!something)", respectively. "if (something)" and if "(!something)", respectively, and for pointers
we prefer "if (some_pointer != NULL)" or "if (some_pointer == NULL)".
We do not use the TAB character for indentation in the C sources. We do not use the TAB character for indentation in the C sources.
Lines do not exceed 80 characters. Lines do not exceed 80 characters.
Other rules can be inferred by inspecting the libpng source. Other rules can be inferred by inspecting the libpng source.
XVI. Y2K Compliance in libpng
Since the PNG Development group is an ad-hoc body, we can't make
an official declaration.
This is your unofficial assurance that libpng from version 0.71 and
upward through 1.6.23 are Y2K compliant. It is my belief that earlier
versions were also Y2K compliant.
Libpng only has two year fields. One is a 2-byte unsigned integer
that will hold years up to 65535. The other, which is deprecated,
holds the date in text format, and will hold years up to 9999.
The integer is
"png_uint_16 year" in png_time_struct.
The string is
"char time_buffer[29]" in png_struct. This is no longer used
in libpng-1.6.x and will be removed from libpng-1.7.0.
There are seven time-related functions:
png_convert_to_rfc_1123_buffer() in png.c
(formerly png_convert_to_rfc_1152() in error, and
also formerly png_convert_to_rfc_1123())
png_convert_from_struct_tm() in pngwrite.c, called
in pngwrite.c
png_convert_from_time_t() in pngwrite.c
png_get_tIME() in pngget.c
png_handle_tIME() in pngrutil.c, called in pngread.c
png_set_tIME() in pngset.c
png_write_tIME() in pngwutil.c, called in pngwrite.c
All appear to handle dates properly in a Y2K environment. The
png_convert_from_time_t() function calls gmtime() to convert from system
clock time, which returns (year - 1900), which we properly convert to
the full 4-digit year. There is a possibility that applications using
libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
function, or that they are incorrectly passing only a 2-digit year
instead of "year - 1900" into the png_convert_from_struct_tm() function,
but this is not under our control. The libpng documentation has always
stated that it works with 4-digit years, and the APIs have been
documented as such.
The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
integer to hold the year, and can hold years as large as 65535.
zlib, upon which libpng depends, is also Y2K compliant. It contains
no date-related code.
Glenn Randers-Pehrson
libpng maintainer
PNG Development Group

File diff suppressed because it is too large Load Diff

@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
Name: libpng
Description: Loads and saves PNG files
Version: @PNGLIB_VERSION@
Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
Libs.private: @LIBS@
Cflags: -I${includedir}

@ -1,18 +1,24 @@
.TH LIBPNGPF 3 "June 9, 2016" .TH LIBPNGPF 3 "April 14, 2019"
.SH NAME .SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.23 libpng \- Portable Network Graphics (PNG) Reference Library 1.6.37
(private functions) (private functions)
.SH SYNOPSIS .SH SYNOPSIS
\fB#include \fI"pngpriv.h" \fB#include \fI"pngpriv.h"
\fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer \fP\fImaintained\fP\fB, now that the private function prototypes are hidden in pngpriv.h and not accessible to applications. Look in pngpriv.h for the prototypes and a short description of each \fIfunction. \fBAs of libpng version \fP\fI1.5.1\fP\fB, this section is no longer
\fP\fImaintained\fP\fB, now that the private function prototypes are hidden in
\fP\fIpngpriv.h\fP\fB and not accessible to applications. Look in
\fP\fIpngpriv.h\fP\fB for the prototypes and a short description of each
function.
.SH DESCRIPTION .SH DESCRIPTION
The functions previously listed here are used privately by libpng and are not The functions previously listed here are used privately by libpng and are not
available for use by applications. They are not "exported" to applications available for use by applications. They are not "exported" to applications
using shared libraries. using shared libraries.
.SH SEE ALSO .SH "SEE ALSO"
.BR "png"(5), " libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5) .BR "png"(5), " libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
.SH AUTHOR
Glenn Randers-Pehrson .SH AUTHORS
Cosmin Truta, Glenn Randers-Pehrson

@ -1,47 +1,49 @@
.TH PNG 5 "June 9, 2016" .TH PNG 5 "April 14, 2019"
.SH NAME .SH NAME
png \- Portable Network Graphics (PNG) format png \- Portable Network Graphics (PNG) format
.SH DESCRIPTION .SH DESCRIPTION
PNG (Portable Network Graphics) is an extensible file format for the PNG (Portable Network Graphics) is an extensible file format for the
lossless, portable, well-compressed storage of raster images. PNG provides lossless, portable, well-compressed storage of raster images. PNG
a patent-free replacement for GIF and can also replace many provides a patent-free replacement for GIF, and can also replace many
common uses of TIFF. Indexed-color, grayscale, and truecolor images are common uses of TIFF. Indexed-color, grayscale, and truecolor images are
supported, plus an optional alpha channel. Sample depths range from supported, plus an optional alpha channel. Sample depths range from
1 to 16 bits. 1 to 16 bits.
.br .br
PNG is designed to work well in online viewing applications, such
PNG is designed to work well in online viewing applications, such as the as the World Wide Web, so it is fully streamable with a progressive
World Wide Web, so it is fully streamable with a progressive display display option. PNG is robust, providing both full file integrity
option. PNG is robust, providing both full file integrity checking and checking and fast, simple detection of common transmission errors.
fast, simple detection of common transmission errors. Also, PNG can store Also, PNG can store gamma and chromaticity data for improved color
gamma and chromaticity data for improved color matching on heterogeneous matching on heterogeneous platforms.
platforms.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR "libpng"(3), " libpngpf"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5) .BR "libpng"(3), " libpngpf"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
.LP .LP
PNG specification (second edition), November 2003: PNG Specification (Second Edition), November 2003:
.IP .IP
.br .br
<http://www.w3.org/TR/2003/REC-PNG-20031110/ https://www.w3.org/TR/2003/REC-PNG-20031110/
PNG 1.2 specification, July 1999:
.IP
.br
http://png-mng.sourceforge.net/pub/png/spec/1.2/
.LP .LP
PNG 1.0 specification, October 1996: PNG 1.2 Specification, July 1999:
.IP
.br
https://png-mng.sourceforge.io/pub/png/spec/1.2/
.LP
PNG 1.0 Specification, October 1996:
.IP .IP
.br .br
RFC 2083 RFC 2083
.br
https://www.ietf.org/rfc/rfc2083.txt
.IP .IP
.br .br
http://www.ietf.org/rfc/rfc2083.txt or W3C Recommendation
.br .br
or (as a W3C Recommendation) at https://www.w3.org/TR/REC-png-961001
.br
http://www.w3.org/TR/REC-png-961001
.SH AUTHORS .SH AUTHORS
This man page: Glenn Randers-Pehrson This man page: Cosmin Truta, Glenn Randers-Pehrson
.LP .LP
Portable Network Graphics (PNG) Specification (Second Edition) Portable Network Graphics (PNG) Specification (Second Edition)
Information technology - Computer graphics and image processing - Information technology - Computer graphics and image processing -
@ -53,22 +55,30 @@ Glenn Randers-Pehrson and others (png-list).
.LP .LP
Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996): Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
Thomas Boutell and others (png-list). Thomas Boutell and others (png-list).
.LP
.SH COPYRIGHT
.SH COPYRIGHT NOTICE
.LP .LP
This man page is Copyright (c) 1998-2006 Glenn Randers-Pehrson. See png.h This man page is
for conditions of use and distribution. .br
Copyright (c) 2018-2019 Cosmin Truta.
.br
Copyright (c) 1998-2006 Glenn Randers-Pehrson.
.br
See png.h for conditions of use and distribution.
.LP .LP
The PNG Specification (Second Edition) is The PNG Specification (Second Edition) is
.br
Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved. Copyright (c) 2003 W3C. (MIT, ERCIM, Keio), All Rights Reserved.
.LP .LP
The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson. The PNG-1.2 Specification is
.br
Copyright (c) 1999 Glenn Randers-Pehrson.
.br
See the specification for conditions of use and distribution. See the specification for conditions of use and distribution.
.LP .LP
The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of The PNG-1.0 Specification is
Technology. See the specification for conditions of use and distribution. .br
.LP Copyright (c) 1996 Massachusetts Institute of Technology.
.br
See the specification for conditions of use and distribution.
.\" end of man page .\" end of man page

File diff suppressed because it is too large Load Diff

@ -1,72 +1,105 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.6.23, June 9, 2016 * libpng version 1.6.37 - April 14, 2019
* *
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * Copyright (c) 2018-2019 Cosmin Truta
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * 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: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * 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.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.23, June 9, 2016: * libpng versions 0.97, January 1998, through 1.6.35, July 2018:
* Glenn Randers-Pehrson. * Glenn Randers-Pehrson
* libpng versions 1.6.36, December 2018, through 1.6.37, April 2019:
* Cosmin Truta
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
*/ */
/* /*
* COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
* =========================================
* *
* If you modify libpng you may insert additional notices immediately following * PNG Reference Library License version 2
* this sentence. * ---------------------------------------
* *
* This code is released under the libpng license. * * Copyright (c) 1995-2019 The PNG Reference Library Authors.
* * Copyright (c) 2018-2019 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.
* *
* Some files in the "contrib" directory and some configure-generated * The software is supplied "as is", without warranty of any kind,
* files that are distributed with libpng have other copyright owners and * express or implied, including, without limitation, the warranties
* are released under other open source licenses. * 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.
* *
* libpng versions 1.0.7, July 1, 2000 through 1.6.23, June 9, 2016 are * Permission is hereby granted to use, copy, modify, and distribute
* Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are * 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 * 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 * disclaimer and license as libpng-1.0.6 with the following individuals
* added to the list of Contributing Authors: * added to the list of Contributing Authors:
* *
* Simon-Pierre Cadieux * Simon-Pierre Cadieux
* Eric S. Raymond * Eric S. Raymond
* Mans Rullgard * Mans Rullgard
* Cosmin Truta * Cosmin Truta
* Gilles Vollant * Gilles Vollant
* James Yu * James Yu
* Mandar Sahastrabuddhe
* Google Inc.
* Vadim Barkov
* *
* and with the following additions to the disclaimer: * and with the following additions to the disclaimer:
* *
* There is no warranty against interference with your enjoyment of the * There is no warranty against interference with your enjoyment of
* library or against infringement. There is no warranty that our * the library or against infringement. There is no warranty that our
* efforts or the library will fulfill any of your particular purposes * efforts or the library will fulfill any of your particular purposes
* or needs. This library is provided with all faults, and the entire * or needs. This library is provided with all faults, and the entire
* risk of satisfactory quality, performance, accuracy, and effort is with * risk of satisfactory quality, performance, accuracy, and effort is
* the user. * with the user.
* *
* Some files in the "contrib" directory have other copyright owners and * 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. * are released under other open source licenses.
* *
*
* libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
* Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
* libpng-0.96, and are distributed according to the same disclaimer and * 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 * license as libpng-0.96, with the following individuals added to the
* of Contributing Authors: * list of Contributing Authors:
* *
* Tom Lane * Tom Lane
* Glenn Randers-Pehrson * Glenn Randers-Pehrson
* Willem van Schaik * Willem van Schaik
*
* Some files in the "scripts" directory have different copyright owners
* but are also released under this license.
* *
* libpng versions 0.89, June 1996, through 0.96, May 1997, are * libpng versions 0.89, June 1996, through 0.96, May 1997, are
* Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
@ -74,14 +107,14 @@
* libpng-0.88, with the following individuals added to the list of * libpng-0.88, with the following individuals added to the list of
* Contributing Authors: * Contributing Authors:
* *
* John Bowler * John Bowler
* Kevin Bracey * Kevin Bracey
* Sam Bushell * Sam Bushell
* Magnus Holmgren * Magnus Holmgren
* Greg Roelofs * Greg Roelofs
* Tom Tanner * Tom Tanner
* *
* Some files in the "scripts" directory have other copyright owners * Some files in the "scripts" directory have other copyright owners,
* but are released under this license. * but are released under this license.
* *
* libpng versions 0.5, May 1995, through 0.88, January 1996, are * libpng versions 0.5, May 1995, through 0.88, January 1996, are
@ -90,62 +123,49 @@
* For the purposes of this copyright and license, "Contributing Authors" * For the purposes of this copyright and license, "Contributing Authors"
* is defined as the following set of individuals: * is defined as the following set of individuals:
* *
* Andreas Dilger * Andreas Dilger
* Dave Martindale * Dave Martindale
* Guy Eric Schalnat * Guy Eric Schalnat
* Paul Schmidt * Paul Schmidt
* Tim Wegner * Tim Wegner
* *
* The PNG Reference Library is supplied "AS IS". The Contributing Authors * The PNG Reference Library is supplied "AS IS". The Contributing
* and Group 42, Inc. disclaim all warranties, expressed or implied, * Authors and Group 42, Inc. disclaim all warranties, expressed or
* including, without limitation, the warranties of merchantability and of * implied, including, without limitation, the warranties of
* fitness for any purpose. The Contributing Authors and Group 42, Inc. * merchantability and of fitness for any purpose. The Contributing
* assume no liability for direct, indirect, incidental, special, exemplary, * Authors and Group 42, Inc. assume no liability for direct, indirect,
* or consequential damages, which may result from the use of the PNG * incidental, special, exemplary, or consequential damages, which may
* Reference Library, even if advised of the possibility of such damage. * 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 * Permission is hereby granted to use, copy, modify, and distribute this
* source code, or portions hereof, for any purpose, without fee, subject * source code, or portions hereof, for any purpose, without fee, subject
* to the following restrictions: * to the following restrictions:
* *
* 1. The origin of this source code must not be misrepresented. * 1. The origin of this source code must not be misrepresented.
* *
* 2. Altered versions must be plainly marked as such and must not * 2. Altered versions must be plainly marked as such and must not
* be misrepresented as being the original source. * be misrepresented as being the original source.
* *
* 3. This Copyright notice may not be removed or altered from any * 3. This Copyright notice may not be removed or altered from any
* source or altered source distribution. * source or altered source distribution.
* *
* The Contributing Authors and Group 42, Inc. specifically permit, without * The Contributing Authors and Group 42, Inc. specifically permit,
* fee, and encourage the use of this source code as a component to * without fee, and encourage the use of this source code as a component
* supporting the PNG file format in commercial products. If you use this * to supporting the PNG file format in commercial products. If you use
* source code in a product, acknowledgment is not required but would be * this source code in a product, acknowledgment is not required but would
* appreciated. * be appreciated.
* *
* END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
* *
* TRADEMARK: * TRADEMARK
* =========
* *
* The name "libpng" has not been registered by the Copyright owner * The name "libpng" has not been registered by the Copyright owners
* as a trademark in any jurisdiction. However, because libpng has * as a trademark in any jurisdiction. However, because libpng has
* been distributed and maintained world-wide, continually since 1995, * been distributed and maintained world-wide, continually since 1995,
* the Copyright owner claims "common-law trademark protection" in any * the Copyright owners claim "common-law trademark protection" in any
* jurisdiction where common-law trademark is recognized. * jurisdiction where common-law trademark is recognized.
*
* OSI CERTIFICATION:
*
* Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
* a certification mark of the Open Source Initiative. OSI has not addressed
* the additional disclaimers inserted at version 1.0.7.
*
* EXPORT CONTROL:
*
* The Copyright owner believes that the Export Control Classification
* Number (ECCN) for libpng is EAR99, which means not subject to export
* controls or International Traffic in Arms Regulations (ITAR) because
* it is open source, publicly available software, that does not contain
* any encryption software. See the EAR, paragraphs 734.3(b)(3) and
* 734.7(b).
*/ */
/* /*
@ -211,23 +231,25 @@
* 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
* 1.0.7 1 10007 (still compatible) * 1.0.7 1 10007 (still compatible)
* ... * ...
* 1.0.19 10 10019 10.so.0.19[.0] * 1.0.69 10 10069 10.so.0.69[.0]
* ... * ...
* 1.2.56 13 10256 12.so.0.56[.0] * 1.2.59 13 10259 12.so.0.59[.0]
* ... * ...
* 1.5.27 15 10527 15.so.15.27[.0] * 1.4.20 14 10420 14.so.0.20[.0]
* ... * ...
* 1.6.23 16 10623 16.so.16.23[.0] * 1.5.30 15 10530 15.so.15.30[.0]
* ...
* 1.6.37 16 10637 16.so.16.37[.0]
* *
* Henceforth the source version will match the shared-library major * Henceforth the source version will match the shared-library major and
* and minor numbers; the shared-library major version number will be * minor numbers; the shared-library major version number will be used for
* used for changes in backward compatibility, as it is intended. The * changes in backward compatibility, as it is intended.
* PNG_LIBPNG_VER macro, which is not used within libpng but is available * The PNG_LIBPNG_VER macro, which is not used within libpng but is
* for applications, is an unsigned integer of the form xyyzz corresponding * available for applications, is an unsigned integer of the form XYYZZ
* to the source version x.y.z (leading zeros in y and z). Beta versions * corresponding to the source version X.Y.Z (leading zeros in Y and Z).
* were given the previous public release number plus a letter, until * Beta versions were given the previous public release number plus a
* version 1.0.6j; from then on they were given the upcoming public * letter, until version 1.0.6j; from then on they were given the upcoming
* release number plus "betaNN" or "rcNN". * public release number plus "betaNN" or "rcNN".
* *
* Binary incompatibility exists only when applications make direct access * Binary incompatibility exists only when applications make direct access
* to the info_ptr or png_ptr members through png.h, and the compiled * to the info_ptr or png_ptr members through png.h, and the compiled
@ -237,65 +259,8 @@
* in binary compatibility (e.g., when a new feature is added). * in binary compatibility (e.g., when a new feature is added).
* *
* See libpng.txt or libpng.3 for more information. The PNG specification * See libpng.txt or libpng.3 for more information. The PNG specification
* is available as a W3C Recommendation and as an ISO Specification, * is available as a W3C Recommendation and as an ISO/IEC Standard; see
* <http://www.w3.org/TR/2003/REC-PNG-20031110/ * <https://www.w3.org/TR/2003/REC-PNG-20031110/>
*/
/*
* Y2K compliance in libpng:
* =========================
*
* June 9, 2016
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.6.23 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
* that will hold years up to 65535. The other, which is deprecated,
* holds the date in text format, and will hold years up to 9999.
*
* The integer is
* "png_uint_16 year" in png_time_struct.
*
* The string is
* "char time_buffer[29]" in png_struct. This is no longer used
* in libpng-1.6.x and will be removed from libpng-1.7.0.
*
* There are seven time-related functions:
* png.c: png_convert_to_rfc_1123_buffer() in png.c
* (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and
* png_convert_to_rfc_1152() in error prior to libpng-0.98)
* png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
* png_convert_from_time_t() in pngwrite.c
* png_get_tIME() in pngget.c
* png_handle_tIME() in pngrutil.c, called in pngread.c
* png_set_tIME() in pngset.c
* png_write_tIME() in pngwutil.c, called in pngwrite.c
*
* All handle dates properly in a Y2K environment. The
* png_convert_from_time_t() function calls gmtime() to convert from system
* clock time, which returns (year - 1900), which we properly convert to
* the full 4-digit year. There is a possibility that libpng applications
* are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()
* function, or that they are incorrectly passing only a 2-digit year
* instead of "year - 1900" into the png_convert_from_struct_tm() function,
* but this is not under our control. The libpng documentation has always
* stated that it works with 4-digit years, and the APIs have been
* documented as such.
*
* The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
* integer to hold the year, and can hold years as large as 65535.
*
* zlib, upon which libpng depends, is also Y2K compliant. It contains
* no date-related code.
*
* Glenn Randers-Pehrson
* libpng maintainer
* PNG Development Group
*/ */
#ifndef PNG_H #ifndef PNG_H
@ -313,9 +278,8 @@
*/ */
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.23" #define PNG_LIBPNG_VER_STRING "1.6.37"
#define PNG_HEADER_VERSION_STRING \ #define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\n"
" libpng version 1.6.23 - June 9, 2016\n"
#define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16 #define PNG_LIBPNG_VER_DLLNUM 16
@ -323,12 +287,11 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6 #define PNG_LIBPNG_VER_MINOR 6
#define PNG_LIBPNG_VER_RELEASE 23 #define PNG_LIBPNG_VER_RELEASE 37
/* This should match the numeric part of the final component of /* This should be zero for a public release, or non-zero for a
* PNG_LIBPNG_VER_STRING, omitting any leading zero: * development version. [Deprecated]
*/ */
#define PNG_LIBPNG_VER_BUILD 0 #define PNG_LIBPNG_VER_BUILD 0
/* Release Status */ /* Release Status */
@ -348,26 +311,27 @@
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE #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. /* Careful here. At one time, Guy wanted to use 082, but that
* We must not include leading zeros. * 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 * Versions 0.7 through 1.0.0 were in the range 0 to 100 here
* version 1.0.0 was mis-numbered 100 instead of 10000). From * (only version 1.0.0 was mis-numbered 100 instead of 10000).
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release * From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/ */
#define PNG_LIBPNG_VER 10623 /* 1.6.23 */ #define PNG_LIBPNG_VER 10637 /* 1.6.37 */
/* Library configuration: these options cannot be changed after /* Library configuration: these options cannot be changed after
* the library has been built. * the library has been built.
*/ */
#ifndef PNGLCONF_H #ifndef PNGLCONF_H
/* If pnglibconf.h is missing, you can /* If pnglibconf.h is missing, you can
* copy scripts/pnglibconf.h.prebuilt to pnglibconf.h * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
*/ */
# include "pnglibconf.h" # include "pnglibconf.h"
#endif #endif
#ifndef PNG_VERSION_INFO_ONLY #ifndef PNG_VERSION_INFO_ONLY
/* Machine specific configuration. */ /* Machine specific configuration. */
# include "pngconf.h" # include "pngconf.h"
#endif #endif
@ -464,7 +428,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h /* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number. * do not agree upon the version number.
*/ */
typedef char* png_libpng_version_1_6_23; typedef char* png_libpng_version_1_6_37;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
* *
@ -605,8 +569,8 @@ typedef struct png_text_struct
png_charp key; /* keyword, 1-79 character description of "text" */ png_charp key; /* keyword, 1-79 character description of "text" */
png_charp text; /* comment, may be an empty string (ie "") png_charp text; /* comment, may be an empty string (ie "")
or a NULL pointer */ or a NULL pointer */
png_size_t text_length; /* length of the text string */ size_t text_length; /* length of the text string */
png_size_t itxt_length; /* length of the itxt string */ size_t itxt_length; /* length of the itxt string */
png_charp lang; /* language code, 0-79 characters png_charp lang; /* language code, 0-79 characters
or a NULL pointer */ or a NULL pointer */
png_charp lang_key; /* keyword translated UTF-8 string, 0 or more png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
@ -657,17 +621,17 @@ typedef png_time * * png_timepp;
*/ */
typedef struct png_unknown_chunk_t typedef struct png_unknown_chunk_t
{ {
png_byte name[5]; /* Textual chunk name with '\0' terminator */ png_byte name[5]; /* Textual chunk name with '\0' terminator */
png_byte *data; /* Data, should not be modified on read! */ png_byte *data; /* Data, should not be modified on read! */
png_size_t size; size_t size;
/* On write 'location' must be set using the flag values listed below. /* 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 * 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 * 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 * bitmask. On write set only one bit - setting multiple bits may cause the
* chunk to be written in multiple places. * chunk to be written in multiple places.
*/ */
png_byte location; /* mode of operation at read time */ png_byte location; /* mode of operation at read time */
} }
png_unknown_chunk; png_unknown_chunk;
@ -684,7 +648,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
/* Maximum positive integer used in PNG is (2^31)-1 */ /* Maximum positive integer used in PNG is (2^31)-1 */
#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
#define PNG_UINT_32_MAX ((png_uint_32)(-1)) #define PNG_UINT_32_MAX ((png_uint_32)(-1))
#define PNG_SIZE_MAX ((png_size_t)(-1)) #define PNG_SIZE_MAX ((size_t)(-1))
/* These are constants for fixed point values encoded in the /* These are constants for fixed point values encoded in the
* PNG specification manner (x100000) * PNG specification manner (x100000)
@ -781,6 +745,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
#define PNG_INFO_sPLT 0x2000U /* 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_sCAL 0x4000U /* ESR, 1.0.6 */
#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ #define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */
#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
/* This is used for the transformation routines, as some of them /* This is used for the transformation routines, as some of them
* change these values for the row. It also should enable using * change these values for the row. It also should enable using
@ -789,7 +754,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp;
typedef struct png_row_info_struct typedef struct png_row_info_struct
{ {
png_uint_32 width; /* width of row */ png_uint_32 width; /* width of row */
png_size_t rowbytes; /* number of bytes in row */ size_t rowbytes; /* number of bytes in row */
png_byte color_type; /* color type of row */ png_byte color_type; /* color type of row */
png_byte bit_depth; /* bit depth of row */ png_byte bit_depth; /* bit depth of row */
png_byte channels; /* number of channels (1, 2, 3, or 4) */ png_byte channels; /* number of channels (1, 2, 3, or 4) */
@ -808,7 +773,7 @@ typedef png_row_info * * png_row_infopp;
* expected to return the read data in the buffer. * 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_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_rw_ptr, (png_structp, png_bytep, size_t));
typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
int)); int));
@ -945,8 +910,8 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
* signature, and non-zero otherwise. Having num_to_check == 0 or * signature, and non-zero otherwise. Having num_to_check == 0 or
* start > 7 will always fail (ie return non-zero). * start > 7 will always fail (ie return non-zero).
*/ */
PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
png_size_t num_to_check)); size_t num_to_check));
/* Simple signature checking function. This is the same as calling /* Simple signature checking function. This is the same as calling
* png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
@ -965,11 +930,11 @@ PNG_EXPORTA(5, png_structp, png_create_write_struct,
png_error_ptr warn_fn), png_error_ptr warn_fn),
PNG_ALLOCATED); PNG_ALLOCATED);
PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
(png_const_structrp png_ptr)); (png_const_structrp png_ptr));
PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
png_size_t size)); size_t size));
/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
* match up. * match up.
@ -1022,7 +987,7 @@ PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
/* Write a PNG chunk - size, type, (optional) data, CRC. */ /* Write a PNG chunk - size, type, (optional) data, CRC. */
PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
chunk_name, png_const_bytep data, png_size_t length)); chunk_name, png_const_bytep data, size_t length));
/* Write the start of a PNG chunk - length and chunk name. */ /* 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,
@ -1030,7 +995,7 @@ PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
/* Write the data of a PNG chunk started with png_write_chunk_start(). */ /* 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_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
png_const_bytep data, png_size_t length)); png_const_bytep data, size_t length));
/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ /* 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));
@ -1044,7 +1009,7 @@ PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
* the API will be removed in the future. * the API will be removed in the future.
*/ */
PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
png_size_t png_info_struct_size), PNG_DEPRECATED); size_t png_info_struct_size), PNG_DEPRECATED);
/* Writes all the PNG information before the image. */ /* Writes all the PNG information before the image. */
PNG_EXPORT(20, void, png_write_info_before_PLTE, PNG_EXPORT(20, void, png_write_info_before_PLTE,
@ -1141,7 +1106,7 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
* corresponding composited pixel, and the color channels are unassociated * corresponding composited pixel, and the color channels are unassociated
* (not premultiplied). The gamma encoded color channels must be scaled * (not premultiplied). The gamma encoded color channels must be scaled
* according to the contribution and to do this it is necessary to undo * 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 encoding, scale the color values, perform the composition and re-encode
* the values. This is the 'PNG' mode. * the values. This is the 'PNG' mode.
* *
* The alternative is to 'associate' the alpha with the color information by * The alternative is to 'associate' the alpha with the color information by
@ -1197,7 +1162,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
* *
* png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); * 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 * In this case the output is assumed to be something like an sRGB conformant
* display preceeded by a power-law lookup table of power 1.45. This is how * display preceded by a power-law lookup table of power 1.45. This is how
* early Mac systems behaved. * early Mac systems behaved.
* *
* png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
@ -1244,7 +1209,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
* *
* When the default gamma of PNG files doesn't match the output gamma. * 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 * 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 ouput gamma to the * you to provide a default gamma, but it also sets the output gamma to the
* matching value. If you know your PNG files have a gamma that doesn't * 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 * 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 * png_set_alpha_mode always sets the output gamma but only sets the PNG
@ -1695,7 +1660,7 @@ PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
* chunk will cause an error at this point unless it is to be saved. * chunk will cause an error at this point unless it is to be saved.
* positive: The chunk was handled, libpng will ignore/discard it. * positive: The chunk was handled, libpng will ignore/discard it.
* *
* See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about
* how this behavior will change in libpng 1.7 * 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,
@ -1720,7 +1685,7 @@ PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
/* Function to be called when data becomes available */ /* Function to be called when data becomes available */
PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); png_inforp info_ptr, png_bytep buffer, size_t buffer_size));
/* A function which may be called *only* within png_process_data to stop the /* 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 * processing of any more data. The function returns the number of bytes
@ -1729,7 +1694,7 @@ PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
* 'save' is set to true the routine will first save all the pending data and * 'save' is set to true the routine will first save all the pending data and
* will always return 0. * will always return 0.
*/ */
PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save));
/* A function which may be called *only* outside (after) a call to /* 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 * png_process_data. It returns the number of bytes of data to skip in the
@ -1793,7 +1758,8 @@ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
#define PNG_FREE_PLTE 0x1000U #define PNG_FREE_PLTE 0x1000U
#define PNG_FREE_TRNS 0x2000U #define PNG_FREE_TRNS 0x2000U
#define PNG_FREE_TEXT 0x4000U #define PNG_FREE_TEXT 0x4000U
#define PNG_FREE_ALL 0x7fffU #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 */ #define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
@ -1873,7 +1839,7 @@ PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
png_const_inforp info_ptr, png_uint_32 flag)); png_const_inforp info_ptr, png_uint_32 flag));
/* Returns number of bytes needed to hold a transformed row. */ /* Returns number of bytes needed to hold a transformed row. */
PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr,
png_const_inforp info_ptr)); png_const_inforp info_ptr));
#ifdef PNG_INFO_IMAGE_SUPPORTED #ifdef PNG_INFO_IMAGE_SUPPORTED
@ -2012,6 +1978,18 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
png_fixed_point int_blue_Z)) png_fixed_point int_blue_Z))
#endif #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 #ifdef PNG_gAMA_SUPPORTED
PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
png_const_inforp info_ptr, double *file_gamma)) png_const_inforp info_ptr, double *file_gamma))
@ -2030,9 +2008,6 @@ PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED
PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
png_inforp info_ptr, png_uint_16p *hist)); png_inforp info_ptr, png_uint_16p *hist));
#endif
#ifdef PNG_hIST_SUPPORTED
PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
png_inforp info_ptr, png_const_uint_16p hist)); png_inforp info_ptr, png_const_uint_16p hist));
#endif #endif
@ -2233,7 +2208,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
* to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
* it simply resets the behavior to the libpng default. * it simply resets the behavior to the libpng default.
* *
* INTERACTION WTIH USER CHUNK CALLBACKS: * INTERACTION WITH USER CHUNK CALLBACKS:
* The per-chunk handling is always used when there is a png_user_chunk_ptr * 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* * 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 * it is critical and the per-chunk setting is other than ALWAYS. Notice that
@ -2300,8 +2275,10 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
* except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
* be processed by libpng. * 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)); 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 "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
* the result is therefore true (non-zero) if special handling is required, * the result is therefore true (non-zero) if special handling is required,
@ -2309,7 +2286,7 @@ PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
*/ */
PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
png_const_bytep chunk_name)); png_const_bytep chunk_name));
#endif #endif /* SET_UNKNOWN_CHUNKS */
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
@ -2530,33 +2507,37 @@ 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 */ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
# define png_composite(composite, fg, alpha, bg) \ # 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 temp = (png_uint_16)((png_uint_16)(fg) \
+ (png_uint_16)(bg)*(png_uint_16)(255 \ * (png_uint_16)(alpha) \
- (png_uint_16)(alpha)) + 128); \ + (png_uint_16)(bg)*(png_uint_16)(255 \
(composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); } - (png_uint_16)(alpha)) + 128); \
(composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
}
# define png_composite_16(composite, fg, alpha, bg) \ # 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 temp = (png_uint_32)((png_uint_32)(fg) \
+ (png_uint_32)(bg)*(65535 \ * (png_uint_32)(alpha) \
- (png_uint_32)(alpha)) + 32768); \ + (png_uint_32)(bg)*(65535 \
(composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); } - (png_uint_32)(alpha)) + 32768); \
(composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
}
#else /* Standard method using integer division */ #else /* Standard method using integer division */
# define png_composite(composite, fg, alpha, bg) \ # define png_composite(composite, fg, alpha, bg) \
(composite) = \ (composite) = \
(png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \
(png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
127) / 255)) 127) / 255))
# define png_composite_16(composite, fg, alpha, bg) \ # define png_composite_16(composite, fg, alpha, bg) \
(composite) = \ (composite) = \
(png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
(png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
32767) / 65535)) 32767) / 65535))
#endif /* READ_COMPOSITE_NODIV */ #endif /* READ_COMPOSITE_NODIV */
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@ -2592,38 +2573,38 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
* format for negative values, which is almost certainly true. * format for negative values, which is almost certainly true.
*/ */
# define PNG_get_uint_32(buf) \ # define PNG_get_uint_32(buf) \
(((png_uint_32)(*(buf)) << 24) + \ (((png_uint_32)(*(buf)) << 24) + \
((png_uint_32)(*((buf) + 1)) << 16) + \ ((png_uint_32)(*((buf) + 1)) << 16) + \
((png_uint_32)(*((buf) + 2)) << 8) + \ ((png_uint_32)(*((buf) + 2)) << 8) + \
((png_uint_32)(*((buf) + 3)))) ((png_uint_32)(*((buf) + 3))))
/* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the /* 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. * function) incorrectly returned a value of type png_uint_32.
*/ */
# define PNG_get_uint_16(buf) \ # define PNG_get_uint_16(buf) \
((png_uint_16) \ ((png_uint_16) \
(((unsigned int)(*(buf)) << 8) + \ (((unsigned int)(*(buf)) << 8) + \
((unsigned int)(*((buf) + 1))))) ((unsigned int)(*((buf) + 1)))))
# define PNG_get_int_32(buf) \ # define PNG_get_int_32(buf) \
((png_int_32)((*(buf) & 0x80) \ ((png_int_32)((*(buf) & 0x80) \
? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \ ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
: (png_int_32)png_get_uint_32(buf))) : (png_int_32)png_get_uint_32(buf)))
/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
* but defining a macro name prefixed with PNG_PREFIX. * but defining a macro name prefixed with PNG_PREFIX.
*/ */
# ifndef PNG_PREFIX # ifndef PNG_PREFIX
# define png_get_uint_32(buf) PNG_get_uint_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_uint_16(buf) PNG_get_uint_16(buf)
# define png_get_int_32(buf) PNG_get_int_32(buf) # define png_get_int_32(buf) PNG_get_int_32(buf)
# endif # endif
#else #else
# ifdef PNG_PREFIX # ifdef PNG_PREFIX
/* No macros; revert to the (redefined) function */ /* No macros; revert to the (redefined) function */
# define PNG_get_uint_32 (png_get_uint_32) # define PNG_get_uint_32 (png_get_uint_32)
# define PNG_get_uint_16 (png_get_uint_16) # define PNG_get_uint_16 (png_get_uint_16)
# define PNG_get_int_32 (png_get_int_32) # define PNG_get_int_32 (png_get_int_32)
# endif # endif
#endif #endif
@ -2646,7 +2627,7 @@ PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
* The simplified API hides the details of both libpng and the PNG file format * 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 * 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 * in-memory bitmap formats or to be written from the same formats. If these
* formats do not accomodate your needs then you can, and should, use the more * formats do not accommodate your needs then you can, and should, use the more
* sophisticated APIs above - these support a wide variety of in-memory formats * sophisticated APIs above - these support a wide variety of in-memory formats
* and a wide variety of sophisticated transformations to those formats as well * and a wide variety of sophisticated transformations to those formats as well
* as a wide variety of APIs to manipulate ancillary information. * as a wide variety of APIs to manipulate ancillary information.
@ -2752,7 +2733,7 @@ typedef struct
* *
* When the simplified API needs to convert between sRGB and linear colorspaces, * When the simplified API needs to convert between sRGB and linear colorspaces,
* the actual sRGB transfer curve defined in the sRGB specification (see the * the actual sRGB transfer curve defined in the sRGB specification (see the
* article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 * article at <https://en.wikipedia.org/wiki/SRGB>) is used, not the gamma=1/2.2
* approximation used elsewhere in libpng. * approximation used elsewhere in libpng.
* *
* When an alpha channel is present it is expected to denote pixel coverage * When an alpha channel is present it is expected to denote pixel coverage
@ -2807,6 +2788,8 @@ typedef struct
# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ # define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
#endif #endif
#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
/* Commonly used formats have predefined macros. /* Commonly used formats have predefined macros.
* *
* First the single byte (sRGB) formats: * First the single byte (sRGB) formats:
@ -2953,7 +2936,7 @@ typedef struct
* 'flags' field of png_image. * 'flags' field of png_image.
*/ */
#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 #define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
/* This indicates the the RGB values of the in-memory bitmap do not /* This indicates that the RGB values of the in-memory bitmap do not
* correspond to the red, green and blue end-points defined by sRGB. * correspond to the red, green and blue end-points defined by sRGB.
*/ */
@ -3006,7 +2989,7 @@ PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
#endif /* STDIO */ #endif /* STDIO */
PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
png_const_voidp memory, png_size_t size)); png_const_voidp memory, size_t size));
/* The PNG header is read from the given memory buffer. */ /* The PNG header is read from the given memory buffer. */
PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
@ -3119,7 +3102,7 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
* than or equal to the original value. * than or equal to the original value.
* *
* If the function returns false and *memory_bytes was not changed an error * If the function returns false and *memory_bytes was not changed an error
* occured during write. If *memory_bytes was changed, or is not 0 if * 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 * 'memory' was NULL, the write would have succeeded but for the memory
* buffer being too small. *memory_bytes contains the required number of * buffer being too small. *memory_bytes contains the required number of
* bytes and will be bigger that the original value. * bytes and will be bigger that the original value.
@ -3171,9 +3154,9 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ #define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
(((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
12U+3U*(image).colormap_entries/*PLTE data*/+\ 12U+3U*(image).colormap_entries/*PLTE data*/+\
(((image).format&PNG_FORMAT_FLAG_ALPHA)?\ (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
/* A helper for the following macro; if your compiler cannot handle the /* A helper for the following macro; if your compiler cannot handle the
* following macro use this one with the result of * following macro use this one with the result of
@ -3203,7 +3186,7 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
* option and 'onoff' is 0 (off) or non-0 (on). The value returned is given * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given
* by the PNG_OPTION_ defines below. * by the PNG_OPTION_ defines below.
* *
* HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions,
* are detected at run time, however sometimes it may be impossible * 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 * to do this in user mode, in which case it is necessary to discover
* the capabilities in an OS specific way. Such capabilities are * the capabilities in an OS specific way. Such capabilities are
@ -3221,7 +3204,14 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
#endif #endif
#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ #define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ #define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
#define PNG_OPTION_NEXT 6 /* Next option - numbers must be even */ #ifdef PNG_MIPS_MSA_API_SUPPORTED
# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */
#endif
#define PNG_IGNORE_ADLER32 8
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
#endif
#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */
/* Return values: NOTE: there are four values and 'off' is *not* zero */ /* Return values: NOTE: there are four values and 'off' is *not* zero */
#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */
@ -3245,7 +3235,7 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
* one to use is one more than this.) * one to use is one more than this.)
*/ */
#ifdef PNG_EXPORT_LAST_ORDINAL #ifdef PNG_EXPORT_LAST_ORDINAL
PNG_EXPORT_LAST_ORDINAL(245); PNG_EXPORT_LAST_ORDINAL(249);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

@ -1,11 +1,12 @@
/* pngconf.h - machine configurable file for libpng /* pngconf.h - machine-configurable file for libpng
* *
* libpng version 1.6.23, June 9, 2016 * libpng version 1.6.37
* *
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 2018-2019 Cosmin Truta
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -57,14 +58,13 @@
#endif /* PNG_BUILDING_SYMBOL_TABLE */ #endif /* PNG_BUILDING_SYMBOL_TABLE */
/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using /* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
* PNG_NO_CONST; this is no longer supported except for data declarations which * using PNG_NO_CONST. This is no longer supported.
* apparently still cause problems in 2011 on some compilers.
*/ */
#define PNG_CONST const /* backward compatibility only */ #define PNG_CONST const /* backward compatibility only */
/* This controls optimization of the reading of 16-bit and 32-bit values /* This controls optimization of the reading of 16-bit and 32-bit
* from PNG files. It can be set on a per-app-file basis - it * 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. * just changes whether a macro is used when the function is called.
* The library builder sets the default; if read functions are not * The library builder sets the default; if read functions are not
* built into the library the macro implementation is forced on. * built into the library the macro implementation is forced on.
@ -127,7 +127,7 @@
* *
* These cases only differ if the operating system does not use the C * These cases only differ if the operating system does not use the C
* calling convention, at present this just means the above cases * calling convention, at present this just means the above cases
* (x86 DOS/Windows sytems) and, even then, this does not apply to * (x86 DOS/Windows systems) and, even then, this does not apply to
* Cygwin running on those systems. * Cygwin running on those systems.
* *
* Note that the value must be defined in pnglibconf.h so that what * Note that the value must be defined in pnglibconf.h so that what
@ -188,27 +188,27 @@
* compatible with GCC or Visual C because of different calling conventions. * compatible with GCC or Visual C because of different calling conventions.
*/ */
# if PNG_API_RULE == 2 # if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not /* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this* * 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 of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom! * build using Watcom and applications must also be built using Watcom!
*/ */
# define PNGCAPI __watcall # define PNGCAPI __watcall
# endif # endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) # if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl # define PNGCAPI __cdecl
# if PNG_API_RULE == 1 # if PNG_API_RULE == 1
/* If this line results in an error __stdcall is not understood and /* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'. * PNG_API_RULE should not have been set to '1'.
*/ */
# define PNGAPI __stdcall # define PNGAPI __stdcall
# endif # endif
# else # else
/* An older compiler, or one not detected (erroneously) above, /* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct * if necessary override on the command line to get the correct
* variants for the compiler. * variants for the compiler.
*/ */
# ifndef PNGCAPI # ifndef PNGCAPI
# define PNGCAPI _cdecl # define PNGCAPI _cdecl
# endif # endif
@ -225,10 +225,10 @@
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ # if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500) (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC /* older Borland and MSC
* compilers used '__export' and required this to be after * compilers used '__export' and required this to be after
* the type. * the type.
*/ */
# ifndef PNG_EXPORT_TYPE # ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP # define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif # endif
@ -244,9 +244,9 @@
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System # define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */ # else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but /* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!) * this will have to be done for every compile!)
*/ */
# endif /* other system, !OS/2 */ # endif /* other system, !OS/2 */
#endif /* !Windows/x86 */ #endif /* !Windows/x86 */
@ -267,7 +267,7 @@
*/ */
#ifndef PNG_IMPEXP #ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) # 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 # define PNG_IMPEXP PNG_DLL_IMPORT
# endif # endif
@ -340,7 +340,7 @@
* less efficient code. * less efficient code.
*/ */
# if defined(__clang__) && defined(__has_attribute) # if defined(__clang__) && defined(__has_attribute)
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) # if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) # define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif # endif
@ -507,16 +507,18 @@
# error "libpng requires a signed 32-bit (or more) type" # error "libpng requires a signed 32-bit (or more) type"
#endif #endif
#if UINT_MAX > 4294967294 #if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32; typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294 #elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32; typedef unsigned long int png_uint_32;
#else #else
# error "libpng requires an unsigned 32-bit (or more) type" # error "libpng requires an unsigned 32-bit (or more) type"
#endif #endif
/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, /* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
* requires an ISOC90 compiler and relies on consistent behavior of sizeof. * 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.
*/ */
typedef size_t png_size_t; typedef size_t png_size_t;
typedef ptrdiff_t png_ptrdiff_t; typedef ptrdiff_t png_ptrdiff_t;
@ -537,13 +539,12 @@ typedef ptrdiff_t png_ptrdiff_t;
# endif # endif
#endif #endif
/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no /* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
* smaller than png_uint_32. Casts from png_size_t or png_uint_32 to * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are
* png_alloc_size_t are not necessary; in fact, it is recommended not to use * not necessary; in fact, it is recommended not to use them at all, so that
* them at all so that the compiler can complain when something turns out to be * the compiler can complain when something turns out to be problematic.
* problematic.
* *
* Casts in the other direction (from png_alloc_size_t to png_size_t or * Casts in the other direction (from png_alloc_size_t to size_t or
* png_uint_32) should be explicitly applied; however, we do not expect to * png_uint_32) should be explicitly applied; however, we do not expect to
* encounter practical situations that require such conversions. * encounter practical situations that require such conversions.
* *
@ -553,7 +554,7 @@ typedef ptrdiff_t png_ptrdiff_t;
#ifdef PNG_SMALL_SIZE_T #ifdef PNG_SMALL_SIZE_T
typedef png_uint_32 png_alloc_size_t; typedef png_uint_32 png_alloc_size_t;
#else #else
typedef png_size_t png_alloc_size_t; typedef size_t png_alloc_size_t;
#endif #endif
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler /* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
@ -589,8 +590,8 @@ typedef char * png_charp;
typedef const char * png_const_charp; typedef const char * png_const_charp;
typedef png_fixed_point * png_fixed_point_p; typedef png_fixed_point * png_fixed_point_p;
typedef const png_fixed_point * png_const_fixed_point_p; typedef const png_fixed_point * png_const_fixed_point_p;
typedef png_size_t * png_size_tp; typedef size_t * png_size_tp;
typedef const png_size_t * png_const_size_tp; typedef const size_t * png_const_size_tp;
#ifdef PNG_STDIO_SUPPORTED #ifdef PNG_STDIO_SUPPORTED
typedef FILE * png_FILE_p; typedef FILE * png_FILE_p;

@ -1,10 +1,10 @@
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
* *
* Last changed in libpng 1.6.8 [December 19, 2013] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer

@ -1,10 +1,10 @@
/* pngerror.c - stub functions for i/o and memory allocation /* pngerror.c - stub functions for i/o and memory allocation
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
#ifdef PNG_WARNINGS_SUPPORTED #ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */ static void /* PRIVATE */
png_default_warning PNGARG((png_const_structrp png_ptr, png_default_warning PNGARG((png_const_structrp png_ptr,
png_const_charp warning_message)); png_const_charp warning_message));
#endif /* WARNINGS */ #endif /* WARNINGS */
/* This function is called whenever there is a fatal error. This function /* This function is called whenever there is a fatal error. This function
@ -37,7 +37,7 @@ png_default_warning PNGARG((png_const_structrp png_ptr,
#ifdef PNG_ERROR_TEXT_SUPPORTED #ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message), png_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16]; char msg[16];
@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
else else
error_message += offset; error_message += offset;
}
else
{
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
} }
}
} else
{
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
}
}
} }
#endif #endif
if (png_ptr != NULL && png_ptr->error_fn != NULL) if (png_ptr != NULL && png_ptr->error_fn != NULL)
@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN)
*/ */
size_t size_t
png_safecat(png_charp buffer, size_t bufsize, size_t pos, png_safecat(png_charp buffer, size_t bufsize, size_t pos,
png_const_charp string) png_const_charp string)
{ {
if (buffer != NULL && pos < bufsize) if (buffer != NULL && pos < bufsize)
{ {
@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos,
*/ */
png_charp png_charp
png_format_number(png_const_charp start, png_charp end, int format, 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 count = 0; /* number of digits output */
int mincount = 1; /* minimum number required */ int mincount = 1; /* minimum number required */
@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02u: case PNG_NUMBER_FORMAT_02u:
/* Expects at least 2 digits. */ /* Expects at least 2 digits. */
mincount = 2; mincount = 2;
/* FALL THROUGH */ /* FALLTHROUGH */
case PNG_NUMBER_FORMAT_u: case PNG_NUMBER_FORMAT_u:
*--end = digits[number % 10]; *--end = digits[number % 10];
@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02x: case PNG_NUMBER_FORMAT_02x:
/* This format expects at least two digits */ /* This format expects at least two digits */
mincount = 2; mincount = 2;
/* FALL THROUGH */ /* FALLTHROUGH */
case PNG_NUMBER_FORMAT_x: case PNG_NUMBER_FORMAT_x:
*--end = digits[number & 0xf]; *--end = digits[number & 0xf];
@ -233,7 +233,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
} }
if (png_ptr != NULL && png_ptr->warning_fn != NULL) if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
warning_message + offset); warning_message + offset);
else else
png_default_warning(png_ptr, warning_message + offset); png_default_warning(png_ptr, warning_message + offset);
} }
@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
*/ */
void void
png_warning_parameter(png_warning_parameters p, int number, 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) if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
@ -253,7 +253,7 @@ png_warning_parameter(png_warning_parameters p, int number,
void void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, 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]; char buffer[PNG_NUMBER_BUFFER_SIZE];
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
@ -261,7 +261,7 @@ png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
void void
png_warning_parameter_signed(png_warning_parameters p, int number, int format, 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_alloc_size_t u;
png_charp str; png_charp str;
@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
void void
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, 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, /* The internal buffer is just 192 bytes - enough for all our messages,
* overflow doesn't happen because this code checks! If someone figures * overflow doesn't happen because this code checks! If someone figures
@ -391,10 +391,10 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */ void /* PRIVATE */
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
{ {
if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
png_warning(png_ptr, error_message); png_warning(png_ptr, error_message);
else else
png_error(png_ptr, error_message); png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED # ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message) PNG_UNUSED(error_message)
@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */ void /* PRIVATE */
png_app_error(png_const_structrp png_ptr, png_const_charp error_message) png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
{ {
if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
png_warning(png_ptr, error_message); png_warning(png_ptr, error_message);
else else
png_error(png_ptr, error_message); png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED # ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message) PNG_UNUSED(error_message)
@ -425,7 +425,7 @@ png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
* if the character is invalid. * if the character is invalid.
*/ */
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = { static const char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' 'A', 'B', 'C', 'D', 'E', 'F'
}; };
@ -478,7 +478,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) #if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
char msg[18+PNG_MAX_ERROR_TEXT]; char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL) if (png_ptr == NULL)
@ -573,7 +573,7 @@ png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
{ {
# define fixed_message "fixed point overflow in " # define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1) # define fixed_message_ln ((sizeof fixed_message)-1)
int iin; unsigned int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
memcpy(msg, fixed_message, fixed_message_ln); memcpy(msg, fixed_message, fixed_message_ln);
iin = 0; iin = 0;
@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
else else
{ {
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, 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) if (png_ptr->jmp_buf_ptr == NULL)
return NULL; /* new NULL return on OOM */ return NULL; /* new NULL return on OOM */
@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr)
*/ */
static PNG_FUNCTION(void /* PRIVATE */, static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
#ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED
@ -883,9 +883,9 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
*/ */
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
PNG_NORETURN) PNG_NORETURN)
{ {
const png_const_structrp png_ptr = png_nonconst_ptr; png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
/* An error is always logged here, overwriting anything (typically a warning) /* An error is always logged here, overwriting anything (typically a warning)
@ -906,7 +906,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
/* Missing longjmp buffer, the following is to help debugging: */ /* Missing longjmp buffer, the following is to help debugging: */
{ {
size_t pos = png_safecat(image->message, (sizeof image->message), 0, size_t pos = png_safecat(image->message, (sizeof image->message), 0,
"bad longjmp: "); "bad longjmp: ");
png_safecat(image->message, (sizeof image->message), pos, png_safecat(image->message, (sizeof image->message), pos,
error_message); error_message);
} }
@ -920,7 +920,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
void /* PRIVATE */ PNGCBAPI void /* PRIVATE */ PNGCBAPI
png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
{ {
const png_const_structrp png_ptr = png_nonconst_ptr; png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_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. */ /* A warning is only logged if there is no prior warning or error. */

@ -1,10 +1,10 @@
/* pngget.c - retrieval of values from info struct /* pngget.c - retrieval of values from info struct
* *
* Last changed in libpng 1.6.17 [March 26, 2015] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -26,7 +26,7 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
return(0); return(0);
} }
png_size_t PNGAPI size_t PNGAPI
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
{ {
if (png_ptr != NULL && info_ptr != NULL) if (png_ptr != NULL && info_ptr != NULL)
@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm)
png_fixed_point result; png_fixed_point result;
if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
5000) != 0) 5000) != 0)
return result; return (png_uint_32)result;
/* Overflow. */ /* Overflow. */
return 0; return 0;
@ -367,7 +367,7 @@ png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
static png_fixed_point static png_fixed_point
png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
{ {
/* Convert from metres * 1,000,000 to inches * 100,000, meters to /* Convert from meters * 1,000,000 to inches * 100,000, meters to
* inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. * 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 * Notice that this can overflow - a warning is output and 0 is
* returned. * returned.
@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
#ifdef PNG_bKGD_SUPPORTED #ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
png_color_16p *background) png_color_16p *background)
{ {
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 && (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (white_x != NULL) if (white_x != NULL)
*white_x = png_float(png_ptr, *white_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
if (white_y != NULL) if (white_y != NULL)
*white_y = png_float(png_ptr, *white_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
if (red_x != NULL) if (red_x != NULL)
*red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
"cHRM red X"); "cHRM red X");
if (red_y != NULL) if (red_y != NULL)
*red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
"cHRM red Y"); "cHRM red Y");
if (green_x != NULL) if (green_x != NULL)
*green_x = png_float(png_ptr, *green_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
if (green_y != NULL) if (green_y != NULL)
*green_y = png_float(png_ptr, *green_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
if (blue_x != NULL) if (blue_x != NULL)
*blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
"cHRM blue X"); "cHRM blue X");
if (blue_y != NULL) if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
"cHRM blue Y"); "cHRM blue Y");
return (PNG_INFO_cHRM); return (PNG_INFO_cHRM);
} }
@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, 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 *red_X, double *red_Y, double *red_Z, double *green_X,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z) double *blue_Z)
{ {
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{ {
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (red_X != NULL) if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
"cHRM red X"); "cHRM red X");
if (red_Y != NULL) if (red_Y != NULL)
*red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
"cHRM red Y"); "cHRM red Y");
if (red_Z != NULL) if (red_Z != NULL)
*red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
"cHRM red Z"); "cHRM red Z");
if (green_X != NULL) if (green_X != NULL)
*green_X = png_float(png_ptr, *green_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
if (green_Y != NULL) if (green_Y != NULL)
*green_Y = png_float(png_ptr, *green_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
if (green_Z != NULL) if (green_Z != NULL)
*green_Z = png_float(png_ptr, *green_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
if (blue_X != NULL) if (blue_X != NULL)
*blue_X = png_float(png_ptr, *blue_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
if (blue_Y != NULL) if (blue_Y != NULL)
*blue_Y = png_float(png_ptr, *blue_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
if (blue_Z != NULL) if (blue_Z != NULL)
*blue_Z = png_float(png_ptr, *blue_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
return (PNG_INFO_cHRM); return (PNG_INFO_cHRM);
} }
@ -681,8 +681,8 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "gAMA"); png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
file_gamma != NULL) file_gamma != NULL)
{ {
*file_gamma = info_ptr->colorspace.gamma; *file_gamma = info_ptr->colorspace.gamma;
return (PNG_INFO_gAMA); return (PNG_INFO_gAMA);
@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
file_gamma != NULL) file_gamma != NULL)
{ {
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
"png_get_gAMA"); "png_get_gAMA");
return (PNG_INFO_gAMA); return (PNG_INFO_gAMA);
} }
@ -741,8 +741,7 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
if (png_ptr != NULL && info_ptr != NULL && if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_iCCP) != 0 && (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
name != NULL && compression_type != NULL && profile != NULL && name != NULL && profile != NULL && proflen != NULL)
proflen != NULL)
{ {
*name = info_ptr->iccp_name; *name = info_ptr->iccp_name;
*profile = info_ptr->iccp_profile; *profile = info_ptr->iccp_profile;
@ -750,11 +749,13 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
/* This is somewhat irrelevant since the profile data returned has /* This is somewhat irrelevant since the profile data returned has
* actually been uncompressed. * actually been uncompressed.
*/ */
*compression_type = PNG_COMPRESSION_TYPE_BASE; if (compression_type != NULL)
*compression_type = PNG_COMPRESSION_TYPE_BASE;
return (PNG_INFO_iCCP); return (PNG_INFO_iCCP);
} }
return (0); return (0);
} }
#endif #endif
@ -773,6 +774,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
} }
#endif #endif
#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);
}
#endif
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
@ -901,7 +931,7 @@ 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"); *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
"sCAL height"); "sCAL height");
return (PNG_INFO_sCAL); return (PNG_INFO_sCAL);
} }
@ -1135,7 +1165,7 @@ png_get_user_chunk_ptr(png_const_structrp png_ptr)
} }
#endif #endif
png_size_t PNGAPI size_t PNGAPI
png_get_compression_buffer_size(png_const_structrp png_ptr) png_get_compression_buffer_size(png_const_structrp png_ptr)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)

@ -1,10 +1,10 @@
/* pnginfo.h - header file for PNG reference library /* pnginfo.h - header file for PNG reference library
* *
* Last changed in libpng 1.6.1 [March 28, 2013] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -55,10 +55,10 @@
struct png_info_def struct png_info_def
{ {
/* The following are necessary for every PNG file */ /* The following are necessary for every PNG file */
png_uint_32 width; /* width of image in pixels (from IHDR) */ 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 height; /* height of image in pixels (from IHDR) */
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
png_size_t rowbytes; /* bytes needed to hold an untransformed row */ size_t rowbytes; /* bytes needed to hold an untransformed row */
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ 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_palette; /* number of color entries in "palette" (PLTE) */
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif #endif
#ifdef PNG_eXIf_SUPPORTED
int num_exif; /* Added at libpng-1.6.31 */
png_bytep exif;
# ifdef PNG_READ_eXIf_SUPPORTED
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
# endif
#endif
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the /* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a * various palette entries, so that a viewer can intelligently select a
@ -239,7 +247,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* The sCAL chunk describes the actual physical dimensions of the /* The sCAL chunk describes the actual physical dimensions of the
* subject matter of the graphic. The chunk contains a unit specification * subject matter of the graphic. The chunk contains a unit specification
* a byte value, and two ASCII strings representing floating-point * a byte value, and two ASCII strings representing floating-point
* values. The values are width and height corresponsing to one pixel * values. The values are width and height corresponding to one pixel
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
* non-zero. * non-zero.
*/ */

@ -1,213 +1,219 @@
/* pnglibconf.h - library build configuration */ /* pnglibconf.h - library build configuration */
/* libpng version 1.6.23, June 9, 2016 */ /* libpng version 1.6.37 */
/* Copyright (c) 1998-2016 Glenn Randers-Pehrson */ /* Copyright (c) 2018-2019 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */ /* This code is released under the libpng license. */
/* and license in png.h */ /* For conditions of distribution and use, see the disclaimer */
/* and license in png.h */
/* pnglibconf.h */
/* Machine generated file: DO NOT EDIT */ /* pnglibconf.h */
/* Derived from: scripts/pnglibconf.dfa */ /* Machine generated file: DO NOT EDIT */
#ifndef PNGLCONF_H /* Derived from: scripts/pnglibconf.dfa */
#define PNGLCONF_H #ifndef PNGLCONF_H
/* options */ #define PNGLCONF_H
#define PNG_16BIT_SUPPORTED /* options */
#define PNG_ALIGNED_MEMORY_SUPPORTED #define PNG_16BIT_SUPPORTED
/*#undef PNG_ARM_NEON_API_SUPPORTED*/ #define PNG_ALIGNED_MEMORY_SUPPORTED
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ /*#undef PNG_ARM_NEON_API_SUPPORTED*/
#define PNG_BENIGN_ERRORS_SUPPORTED /*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
#define PNG_BENIGN_READ_ERRORS_SUPPORTED #define PNG_BENIGN_ERRORS_SUPPORTED
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ #define PNG_BENIGN_READ_ERRORS_SUPPORTED
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED /*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
#define PNG_COLORSPACE_SUPPORTED #define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED #define PNG_COLORSPACE_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED
#define PNG_EASY_ACCESS_SUPPORTED #define PNG_CONVERT_tIME_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ #define PNG_EASY_ACCESS_SUPPORTED
#define PNG_ERROR_TEXT_SUPPORTED /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_FIXED_POINT_SUPPORTED #define PNG_ERROR_TEXT_SUPPORTED
#define PNG_FLOATING_ARITHMETIC_SUPPORTED #define PNG_FIXED_POINT_SUPPORTED
#define PNG_FLOATING_POINT_SUPPORTED #define PNG_FLOATING_ARITHMETIC_SUPPORTED
#define PNG_FORMAT_AFIRST_SUPPORTED #define PNG_FLOATING_POINT_SUPPORTED
#define PNG_FORMAT_BGR_SUPPORTED #define PNG_FORMAT_AFIRST_SUPPORTED
#define PNG_GAMMA_SUPPORTED #define PNG_FORMAT_BGR_SUPPORTED
#define PNG_GET_PALETTE_MAX_SUPPORTED #define PNG_GAMMA_SUPPORTED
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED #define PNG_GET_PALETTE_MAX_SUPPORTED
#define PNG_INCH_CONVERSIONS_SUPPORTED #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED #define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_IO_STATE_SUPPORTED #define PNG_INFO_IMAGE_SUPPORTED
#define PNG_MNG_FEATURES_SUPPORTED #define PNG_IO_STATE_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED #define PNG_MNG_FEATURES_SUPPORTED
#define PNG_PROGRESSIVE_READ_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED /*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
#define PNG_READ_ALPHA_MODE_SUPPORTED /*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED #define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED #define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_BGR_SUPPORTED #define PNG_READ_ALPHA_MODE_SUPPORTED
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED #define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED #define PNG_READ_BGR_SUPPORTED
#define PNG_READ_EXPAND_16_SUPPORTED #define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED #define PNG_READ_COMPOSITE_NODIV_SUPPORTED
#define PNG_READ_FILLER_SUPPORTED #define PNG_READ_COMPRESSED_TEXT_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED #define PNG_READ_EXPAND_16_SUPPORTED
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED #define PNG_READ_EXPAND_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED #define PNG_READ_FILLER_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED #define PNG_READ_GAMMA_SUPPORTED
#define PNG_READ_INT_FUNCTIONS_SUPPORTED #define PNG_READ_GET_PALETTE_MAX_SUPPORTED
#define PNG_READ_INVERT_ALPHA_SUPPORTED #define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED #define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED #define PNG_READ_INT_FUNCTIONS_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED #define PNG_READ_INVERT_ALPHA_SUPPORTED
#define PNG_READ_PACK_SUPPORTED #define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_QUANTIZE_SUPPORTED #define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_READ_RGB_TO_GRAY_SUPPORTED #define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_SCALE_16_TO_8_SUPPORTED #define PNG_READ_PACK_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED #define PNG_READ_QUANTIZE_SUPPORTED
#define PNG_READ_STRIP_16_TO_8_SUPPORTED #define PNG_READ_RGB_TO_GRAY_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED #define PNG_READ_SCALE_16_TO_8_SUPPORTED
#define PNG_READ_SUPPORTED #define PNG_READ_SHIFT_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED #define PNG_READ_STRIP_16_TO_8_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED #define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_READ_TEXT_SUPPORTED #define PNG_READ_SUPPORTED
#define PNG_READ_TRANSFORMS_SUPPORTED #define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED #define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_USER_CHUNKS_SUPPORTED #define PNG_READ_TEXT_SUPPORTED
#define PNG_READ_USER_TRANSFORM_SUPPORTED #define PNG_READ_TRANSFORMS_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED #define PNG_READ_USER_CHUNKS_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED #define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_hIST_SUPPORTED #define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED #define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_iTXt_SUPPORTED #define PNG_READ_eXIf_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED #define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED #define PNG_READ_hIST_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED #define PNG_READ_iCCP_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED #define PNG_READ_iTXt_SUPPORTED
#define PNG_READ_sCAL_SUPPORTED #define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_sPLT_SUPPORTED #define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_sRGB_SUPPORTED #define PNG_READ_pHYs_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED #define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_tIME_SUPPORTED #define PNG_READ_sCAL_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED #define PNG_READ_sPLT_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED #define PNG_READ_sRGB_SUPPORTED
#define PNG_SAVE_INT_32_SUPPORTED #define PNG_READ_tEXt_SUPPORTED
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_READ_tIME_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED #define PNG_READ_tRNS_SUPPORTED
#define PNG_SETJMP_SUPPORTED #define PNG_READ_zTXt_SUPPORTED
#define PNG_SET_OPTION_SUPPORTED #define PNG_SAVE_INT_32_SUPPORTED
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED #define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED #define PNG_SETJMP_SUPPORTED
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED #define PNG_SET_OPTION_SUPPORTED
#define PNG_SIMPLIFIED_READ_SUPPORTED #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED #define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED #define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED #define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_STDIO_SUPPORTED #define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
#define PNG_TEXT_SUPPORTED #define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_TIME_RFC1123_SUPPORTED #define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_UNKNOWN_CHUNKS_SUPPORTED #define PNG_STDIO_SUPPORTED
#define PNG_USER_CHUNKS_SUPPORTED #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_LIMITS_SUPPORTED #define PNG_TEXT_SUPPORTED
#define PNG_USER_MEM_SUPPORTED #define PNG_TIME_RFC1123_SUPPORTED
#define PNG_USER_TRANSFORM_INFO_SUPPORTED #define PNG_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_USER_TRANSFORM_PTR_SUPPORTED #define PNG_USER_CHUNKS_SUPPORTED
#define PNG_WARNINGS_SUPPORTED #define PNG_USER_LIMITS_SUPPORTED
#define PNG_WRITE_16BIT_SUPPORTED #define PNG_USER_MEM_SUPPORTED
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #define PNG_USER_TRANSFORM_INFO_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED #define PNG_USER_TRANSFORM_PTR_SUPPORTED
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_WARNINGS_SUPPORTED
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED #define PNG_WRITE_16BIT_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED #define PNG_WRITE_BGR_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED #define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
#define PNG_WRITE_FILTER_SUPPORTED #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
#define PNG_WRITE_FLUSH_SUPPORTED #define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED #define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED #define PNG_WRITE_FILTER_SUPPORTED
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED #define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED #define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED #define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED #define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED #define PNG_WRITE_INVERT_ALPHA_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED #define PNG_WRITE_INVERT_SUPPORTED
#define PNG_WRITE_SUPPORTED #define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED #define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED #define PNG_WRITE_PACK_SUPPORTED
#define PNG_WRITE_TEXT_SUPPORTED #define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_WRITE_TRANSFORMS_SUPPORTED #define PNG_WRITE_SUPPORTED
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED #define PNG_WRITE_SWAP_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #define PNG_WRITE_TEXT_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED #define PNG_WRITE_TRANSFORMS_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED #define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED #define PNG_WRITE_USER_TRANSFORM_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_iTXt_SUPPORTED #define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED #define PNG_WRITE_eXIf_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED #define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED #define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED #define PNG_WRITE_iCCP_SUPPORTED
#define PNG_WRITE_sCAL_SUPPORTED #define PNG_WRITE_iTXt_SUPPORTED
#define PNG_WRITE_sPLT_SUPPORTED #define PNG_WRITE_oFFs_SUPPORTED
#define PNG_WRITE_sRGB_SUPPORTED #define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED #define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED #define PNG_WRITE_sBIT_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED #define PNG_WRITE_sCAL_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED #define PNG_WRITE_sPLT_SUPPORTED
#define PNG_bKGD_SUPPORTED #define PNG_WRITE_sRGB_SUPPORTED
#define PNG_cHRM_SUPPORTED #define PNG_WRITE_tEXt_SUPPORTED
#define PNG_gAMA_SUPPORTED #define PNG_WRITE_tIME_SUPPORTED
#define PNG_hIST_SUPPORTED #define PNG_WRITE_tRNS_SUPPORTED
#define PNG_iCCP_SUPPORTED #define PNG_WRITE_zTXt_SUPPORTED
#define PNG_iTXt_SUPPORTED #define PNG_bKGD_SUPPORTED
#define PNG_oFFs_SUPPORTED #define PNG_cHRM_SUPPORTED
#define PNG_pCAL_SUPPORTED #define PNG_eXIf_SUPPORTED
#define PNG_pHYs_SUPPORTED #define PNG_gAMA_SUPPORTED
#define PNG_sBIT_SUPPORTED #define PNG_hIST_SUPPORTED
#define PNG_sCAL_SUPPORTED #define PNG_iCCP_SUPPORTED
#define PNG_sPLT_SUPPORTED #define PNG_iTXt_SUPPORTED
#define PNG_sRGB_SUPPORTED #define PNG_oFFs_SUPPORTED
#define PNG_tEXt_SUPPORTED #define PNG_pCAL_SUPPORTED
#define PNG_tIME_SUPPORTED #define PNG_pHYs_SUPPORTED
#define PNG_tRNS_SUPPORTED #define PNG_sBIT_SUPPORTED
#define PNG_zTXt_SUPPORTED #define PNG_sCAL_SUPPORTED
/* end of options */ #define PNG_sPLT_SUPPORTED
/* settings */ #define PNG_sRGB_SUPPORTED
#define PNG_API_RULE 0 #define PNG_tEXt_SUPPORTED
#define PNG_DEFAULT_READ_MACROS 1 #define PNG_tIME_SUPPORTED
#define PNG_GAMMA_THRESHOLD_FIXED 5000 #define PNG_tRNS_SUPPORTED
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE #define PNG_zTXt_SUPPORTED
#define PNG_INFLATE_BUF_SIZE 1024 /* end of options */
#define PNG_LINKAGE_API extern /* settings */
#define PNG_LINKAGE_CALLBACK extern #define PNG_API_RULE 0
#define PNG_LINKAGE_DATA extern #define PNG_DEFAULT_READ_MACROS 1
#define PNG_LINKAGE_FUNCTION extern #define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_MAX_GAMMA_8 11 #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
#define PNG_QUANTIZE_BLUE_BITS 5 #define PNG_INFLATE_BUF_SIZE 1024
#define PNG_QUANTIZE_GREEN_BITS 5 #define PNG_LINKAGE_API extern
#define PNG_QUANTIZE_RED_BITS 5 #define PNG_LINKAGE_CALLBACK extern
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) #define PNG_LINKAGE_DATA extern
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 #define PNG_LINKAGE_FUNCTION extern
#define PNG_USER_CHUNK_CACHE_MAX 1000 #define PNG_MAX_GAMMA_8 11
#define PNG_USER_CHUNK_MALLOC_MAX 8000000 #define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_USER_HEIGHT_MAX 1000000 #define PNG_QUANTIZE_GREEN_BITS 5
#define PNG_USER_WIDTH_MAX 1000000 #define PNG_QUANTIZE_RED_BITS 5
#define PNG_ZBUF_SIZE 8192 #define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
#define PNG_ZLIB_VERNUM 0x1280 #define PNG_TEXT_Z_DEFAULT_STRATEGY 0
#define PNG_Z_DEFAULT_COMPRESSION (-1) #define PNG_USER_CHUNK_CACHE_MAX 1000
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 #define PNG_USER_CHUNK_MALLOC_MAX 8000000
#define PNG_Z_DEFAULT_STRATEGY 1 #define PNG_USER_HEIGHT_MAX 1000000
#define PNG_sCAL_PRECISION 5 #define PNG_USER_WIDTH_MAX 1000000
#define PNG_sRGB_PROFILE_CHECKS 2 #define PNG_ZBUF_SIZE 8192
/* end of settings */ #define PNG_ZLIB_VERNUM 0 /* unknown */
#endif /* PNGLCONF_H */ #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 */

@ -1,10 +1,10 @@
/* pngmem.c - stub functions for memory allocation /* pngmem.c - stub functions for memory allocation
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
*/ */
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), 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 /* 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 * allocators have also been removed in 1.6.0, so any 16-bit system now has
@ -107,9 +107,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
*/ */
static png_voidp static png_voidp
png_malloc_array_checked(png_const_structrp png_ptr, int nelements, png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
size_t element_size) size_t element_size)
{ {
png_alloc_size_t req = nelements; /* known to be > 0 */ png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
if (req <= PNG_SIZE_MAX/element_size) if (req <= PNG_SIZE_MAX/element_size)
return png_malloc_base(png_ptr, req * element_size); return png_malloc_base(png_ptr, req * element_size);
@ -120,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_array,(png_const_structrp png_ptr, int nelements, 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) if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc"); png_error(png_ptr, "internal error: array alloc");
@ -130,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */, PNG_FUNCTION(png_voidp /* PRIVATE */,
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, 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: */ /* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 || if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
@ -143,7 +143,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
if (add_elements <= INT_MAX - old_elements) if (add_elements <= INT_MAX - old_elements)
{ {
png_voidp new_array = png_malloc_array_checked(png_ptr, 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) if (new_array != NULL)
{ {
@ -154,7 +154,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
memcpy(new_array, old_array, element_size*(unsigned)old_elements); memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0, memset((char*)new_array + element_size*(unsigned)old_elements, 0,
element_size*(unsigned)add_elements); element_size*(unsigned)add_elements);
return new_array; return new_array;
} }
@ -187,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(png_voidp,PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED PNG_DEPRECATED) PNG_ALLOCATED PNG_DEPRECATED)
{ {
png_voidp ret; png_voidp ret;
@ -210,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
*/ */
PNG_FUNCTION(png_voidp,PNGAPI PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED) PNG_ALLOCATED)
{ {
if (png_ptr != NULL) if (png_ptr != NULL)
{ {

@ -1,10 +1,10 @@
/* pngpread.c - read a png file in push mode /* pngpread.c - read a png file in push mode
* *
* Last changed in libpng 1.6.23 [June 9, 2016] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -34,7 +34,7 @@ if (png_ptr->buffer_size < N) \
void PNGAPI void PNGAPI
png_process_data(png_structrp png_ptr, png_inforp info_ptr, png_process_data(png_structrp png_ptr, png_inforp info_ptr,
png_bytep buffer, png_size_t buffer_size) png_bytep buffer, size_t buffer_size)
{ {
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
@ -47,7 +47,7 @@ png_process_data(png_structrp png_ptr, png_inforp info_ptr,
} }
} }
png_size_t PNGAPI size_t PNGAPI
png_process_data_pause(png_structrp png_ptr, int save) png_process_data_pause(png_structrp png_ptr, int save)
{ {
if (png_ptr != NULL) if (png_ptr != NULL)
@ -60,7 +60,7 @@ png_process_data_pause(png_structrp png_ptr, int save)
else else
{ {
/* This includes any pending saved bytes: */ /* This includes any pending saved bytes: */
png_size_t remaining = png_ptr->buffer_size; size_t remaining = png_ptr->buffer_size;
png_ptr->buffer_size = 0; png_ptr->buffer_size = 0;
/* So subtract the saved buffer size, unless all the data /* So subtract the saved buffer size, unless all the data
@ -77,11 +77,11 @@ png_process_data_pause(png_structrp png_ptr, int save)
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_process_data_skip(png_structrp png_ptr) png_process_data_skip(png_structrp png_ptr)
{ {
/* TODO: Deprecate and remove this API. /* TODO: Deprecate and remove this API.
* Somewhere the implementation of this seems to have been lost, * Somewhere the implementation of this seems to have been lost,
* or abandoned. It was only to support some internal back-door access * or abandoned. It was only to support some internal back-door access
* to png_struct) in libpng-1.4.x. * to png_struct) in libpng-1.4.x.
*/ */
png_app_warning(png_ptr, png_app_warning(png_ptr,
"png_process_data_skip is not implemented in any current version of libpng"); "png_process_data_skip is not implemented in any current version of libpng");
return 0; return 0;
@ -133,8 +133,8 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{ {
png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
num_to_check = 8 - num_checked; size_t num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check) if (png_ptr->buffer_size < num_to_check)
{ {
@ -189,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_crc_read(png_ptr, chunk_tag, 4); png_crc_read(png_ptr, chunk_tag, 4);
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
png_check_chunk_name(png_ptr, png_ptr->chunk_name); png_check_chunk_name(png_ptr, png_ptr->chunk_name);
png_check_chunk_length(png_ptr, png_ptr->push_length);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
} }
@ -410,14 +411,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
{ {
PNG_PUSH_SAVE_BUFFER_IF_FULL PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
PNG_HANDLE_CHUNK_AS_DEFAULT); PNG_HANDLE_CHUNK_AS_DEFAULT);
} }
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
} }
void PNGCBAPI void PNGCBAPI
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
{ {
png_bytep ptr; png_bytep ptr;
@ -427,7 +428,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
ptr = buffer; ptr = buffer;
if (png_ptr->save_buffer_size != 0) if (png_ptr->save_buffer_size != 0)
{ {
png_size_t save_size; size_t save_size;
if (length < png_ptr->save_buffer_size) if (length < png_ptr->save_buffer_size)
save_size = length; save_size = length;
@ -444,7 +445,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
} }
if (length != 0 && png_ptr->current_buffer_size != 0) if (length != 0 && png_ptr->current_buffer_size != 0)
{ {
png_size_t save_size; size_t save_size;
if (length < png_ptr->current_buffer_size) if (length < png_ptr->current_buffer_size)
save_size = length; save_size = length;
@ -466,7 +467,7 @@ png_push_save_buffer(png_structrp png_ptr)
{ {
if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
{ {
png_size_t i, istop; size_t i, istop;
png_bytep sp; png_bytep sp;
png_bytep dp; png_bytep dp;
@ -481,7 +482,7 @@ png_push_save_buffer(png_structrp png_ptr)
if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
png_ptr->save_buffer_max) png_ptr->save_buffer_max)
{ {
png_size_t new_max; size_t new_max;
png_bytep old_buffer; png_bytep old_buffer;
if (png_ptr->save_buffer_size > PNG_SIZE_MAX - if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
@ -493,7 +494,7 @@ png_push_save_buffer(png_structrp png_ptr)
new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
old_buffer = png_ptr->save_buffer; old_buffer = png_ptr->save_buffer;
png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
(png_size_t)new_max); (size_t)new_max);
if (png_ptr->save_buffer == NULL) if (png_ptr->save_buffer == NULL)
{ {
@ -521,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length) size_t buffer_length)
{ {
png_ptr->current_buffer = buffer; png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length; png_ptr->current_buffer_size = buffer_length;
@ -561,7 +562,7 @@ png_push_read_IDAT(png_structrp png_ptr)
if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
{ {
png_size_t save_size = png_ptr->save_buffer_size; size_t save_size = png_ptr->save_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size; png_uint_32 idat_size = png_ptr->idat_size;
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
@ -571,7 +572,7 @@ png_push_read_IDAT(png_structrp png_ptr)
* will break on either 16-bit or 64-bit platforms. * will break on either 16-bit or 64-bit platforms.
*/ */
if (idat_size < save_size) if (idat_size < save_size)
save_size = (png_size_t)idat_size; save_size = (size_t)idat_size;
else else
idat_size = (png_uint_32)save_size; idat_size = (png_uint_32)save_size;
@ -588,7 +589,7 @@ png_push_read_IDAT(png_structrp png_ptr)
if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
{ {
png_size_t save_size = png_ptr->current_buffer_size; size_t save_size = png_ptr->current_buffer_size;
png_uint_32 idat_size = png_ptr->idat_size; png_uint_32 idat_size = png_ptr->idat_size;
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
@ -597,7 +598,7 @@ png_push_read_IDAT(png_structrp png_ptr)
* larger - this cannot overflow. * larger - this cannot overflow.
*/ */
if (idat_size < save_size) if (idat_size < save_size)
save_size = (png_size_t)idat_size; save_size = (size_t)idat_size;
else else
idat_size = (png_uint_32)save_size; idat_size = (png_uint_32)save_size;
@ -624,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length) size_t buffer_length)
{ {
/* The caller checks for a non-zero buffer length. */ /* The caller checks for a non-zero buffer length. */
if (!(buffer_length > 0) || buffer == NULL) if (!(buffer_length > 0) || buffer == NULL)
@ -684,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_warning(png_ptr, "Truncated compressed data in IDAT"); png_warning(png_ptr, "Truncated compressed data in IDAT");
else else
png_error(png_ptr, "Decompression error in IDAT"); {
if (ret == Z_DATA_ERROR)
png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
else
png_error(png_ptr, "Decompression error in IDAT");
}
/* Skip the check on unprocessed input */ /* Skip the check on unprocessed input */
return; return;
@ -782,7 +788,7 @@ png_push_process_row(png_structrp png_ptr)
{ {
if (png_ptr->pass < 6) if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 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)
{ {
@ -966,20 +972,20 @@ png_read_push_finish_row(png_structrp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* Offset to next interlace block in the y direction */
static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; static 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 /* Height of interlace block. This is not currently used - if you need
* it, uncomment it here and in png.h * it, uncomment it here and in png.h
static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
*/ */
#endif #endif
@ -1044,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row)
{ {
if (png_ptr->row_fn != NULL) if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
(int)png_ptr->pass); (int)png_ptr->pass);
} }
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED

@ -1,10 +1,10 @@
/* pngpriv.h - private declarations for use inside libpng /* pngpriv.h - private declarations for use inside libpng
* *
* Last changed in libpng 1.6.22 [May 26, 2016] * Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -35,7 +35,9 @@
* Windows/Visual Studio) there is no effect; the OS specific tests below are * Windows/Visual Studio) there is no effect; the OS specific tests below are
* still required (as of 2011-05-02.) * still required (as of 2011-05-02.)
*/ */
#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ #ifndef _POSIX_SOURCE
# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#endif
#ifndef PNG_VERSION_INFO_ONLY #ifndef PNG_VERSION_INFO_ONLY
/* Standard library headers not required by png.h: */ /* Standard library headers not required by png.h: */
@ -172,7 +174,10 @@
# else /* !defined __ARM_NEON__ */ # else /* !defined __ARM_NEON__ */
/* The 'intrinsics' code simply won't compile without this -mfpu=neon: /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
*/ */
# define PNG_ARM_NEON_IMPLEMENTATION 2 # if !defined(__aarch64__)
/* The assembler code currently does not work on ARM64 */
# define PNG_ARM_NEON_IMPLEMENTATION 2
# endif /* __aarch64__ */
# endif /* __ARM_NEON__ */ # endif /* __ARM_NEON__ */
# endif /* !PNG_ARM_NEON_IMPLEMENTATION */ # endif /* !PNG_ARM_NEON_IMPLEMENTATION */
@ -182,6 +187,90 @@
# endif # endif
#endif /* PNG_ARM_NEON_OPT > 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_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_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
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
# 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
# endif
#endif /* PNG_MIPS_MSA_OPT > 0 */
#if PNG_POWERPC_VSX_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
# define PNG_POWERPC_VSX_IMPLEMENTATION 1
#endif
/* Is this a build of a DLL where compilation of the object modules requires /* 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 * different preprocessor settings to those required for a simple library? If
* so PNG_BUILD_DLL must be set. * so PNG_BUILD_DLL must be set.
@ -374,25 +463,6 @@
# define png_fixed_error(s1,s2) png_err(s1) # define png_fixed_error(s1,s2) png_err(s1)
#endif #endif
/* 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
* const is not cast away.
*/
#ifdef __cplusplus
# define png_voidcast(type, value) static_cast<type>(value)
# define png_constcast(type, value) const_cast<type>(value)
# define png_aligncast(type, value) \
static_cast<type>(static_cast<void*>(value))
# define png_aligncastconst(type, value) \
static_cast<type>(static_cast<const void*>(value))
#else
# define png_voidcast(type, value) (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 /* Some fixed point APIs are still required even if not exported because
* they get used by the corresponding floating point APIs. This magic * they get used by the corresponding floating point APIs. This magic
* deals with this: * deals with this:
@ -407,6 +477,35 @@
/* Other defines specific to compilers can go here. Try to keep /* Other defines specific to compilers can go here. Try to keep
* them inside an appropriate ifdef/endif pair for portability. * 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
* const is not cast away.
*/
#ifdef __cplusplus
# define png_voidcast(type, value) static_cast<type>(value)
# define png_constcast(type, value) const_cast<type>(value)
# define png_aligncast(type, value) \
static_cast<type>(static_cast<void*>(value))
# define png_aligncastconst(type, value) \
static_cast<type>(static_cast<const void*>(value))
#else
# define png_voidcast(type, value) (value)
# ifdef _WIN64
# ifdef __GNUC__
typedef unsigned long long png_ptruint;
# else
typedef unsigned __int64 png_ptruint;
# endif
# else
typedef unsigned long png_ptruint;
# endif
# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
# define png_aligncast(type, value) ((void*)(value))
# define png_aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */
#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ #if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
/* png.c requires the following ANSI-C constants if the conversion of /* png.c requires the following ANSI-C constants if the conversion of
@ -420,10 +519,10 @@
# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
/* We need to check that <math.h> hasn't already been included earlier /* We need to check that <math.h> hasn't already been included earlier
* as it seems it doesn't agree with <fp.h>, yet we should really use * as it seems it doesn't agree with <fp.h>, yet we should really use
* <fp.h> if possible. * <fp.h> if possible.
*/ */
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) # if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
# include <fp.h> # include <fp.h>
# endif # endif
@ -431,9 +530,9 @@
# include <math.h> # include <math.h>
# endif # endif
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) # if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
/* Amiga SAS/C: We must include builtin FPU functions when compiling using /* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881 * MATH=68881
*/ */
# include <m68881.h> # include <m68881.h>
# endif # endif
#endif #endif
@ -504,7 +603,8 @@
/* This implicitly assumes alignment is always to a power of 2. */ /* This implicitly assumes alignment is always to a power of 2. */
#ifdef png_alignof #ifdef png_alignof
# define png_isaligned(ptr, type)\ # define png_isaligned(ptr, type)\
((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0) (((type)((const char*)ptr-(const char*)0) & \
(type)(png_alignof(type)-1)) == 0)
#else #else
# define png_isaligned(ptr, type) 0 # define png_isaligned(ptr, type) 0
#endif #endif
@ -521,92 +621,92 @@
* are defined in png.h because they need to be visible to applications * are defined in png.h because they need to be visible to applications
* that call png_set_unknown_chunk(). * that call png_set_unknown_chunk().
*/ */
/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */ /* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */
/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */ /* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */
#define PNG_HAVE_IDAT 0x04 #define PNG_HAVE_IDAT 0x04U
/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */ /* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */
#define PNG_HAVE_IEND 0x10 #define PNG_HAVE_IEND 0x10U
/* 0x20 (unused) */ /* 0x20U (unused) */
/* 0x40 (unused) */ /* 0x40U (unused) */
/* 0x80 (unused) */ /* 0x80U (unused) */
#define PNG_HAVE_CHUNK_HEADER 0x100 #define PNG_HAVE_CHUNK_HEADER 0x100U
#define PNG_WROTE_tIME 0x200 #define PNG_WROTE_tIME 0x200U
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 #define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
#define PNG_BACKGROUND_IS_GRAY 0x800 #define PNG_BACKGROUND_IS_GRAY 0x800U
#define PNG_HAVE_PNG_SIGNATURE 0x1000 #define PNG_HAVE_PNG_SIGNATURE 0x1000U
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
/* 0x4000 (unused) */ /* 0x4000U (unused) */
#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */ #define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */
/* Flags for the transformations the PNG library does on the image data */ /* Flags for the transformations the PNG library does on the image data */
#define PNG_BGR 0x0001 #define PNG_BGR 0x0001U
#define PNG_INTERLACE 0x0002 #define PNG_INTERLACE 0x0002U
#define PNG_PACK 0x0004 #define PNG_PACK 0x0004U
#define PNG_SHIFT 0x0008 #define PNG_SHIFT 0x0008U
#define PNG_SWAP_BYTES 0x0010 #define PNG_SWAP_BYTES 0x0010U
#define PNG_INVERT_MONO 0x0020 #define PNG_INVERT_MONO 0x0020U
#define PNG_QUANTIZE 0x0040 #define PNG_QUANTIZE 0x0040U
#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */ #define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */
#define PNG_BACKGROUND_EXPAND 0x0100 #define PNG_BACKGROUND_EXPAND 0x0100U
#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */ #define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */
#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */ #define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */
#define PNG_RGBA 0x0800 #define PNG_RGBA 0x0800U
#define PNG_EXPAND 0x1000 #define PNG_EXPAND 0x1000U
#define PNG_GAMMA 0x2000 #define PNG_GAMMA 0x2000U
#define PNG_GRAY_TO_RGB 0x4000 #define PNG_GRAY_TO_RGB 0x4000U
#define PNG_FILLER 0x8000 #define PNG_FILLER 0x8000U
#define PNG_PACKSWAP 0x10000 #define PNG_PACKSWAP 0x10000U
#define PNG_SWAP_ALPHA 0x20000 #define PNG_SWAP_ALPHA 0x20000U
#define PNG_STRIP_ALPHA 0x40000 #define PNG_STRIP_ALPHA 0x40000U
#define PNG_INVERT_ALPHA 0x80000 #define PNG_INVERT_ALPHA 0x80000U
#define PNG_USER_TRANSFORM 0x100000 #define PNG_USER_TRANSFORM 0x100000U
#define PNG_RGB_TO_GRAY_ERR 0x200000 #define PNG_RGB_TO_GRAY_ERR 0x200000U
#define PNG_RGB_TO_GRAY_WARN 0x400000 #define PNG_RGB_TO_GRAY_WARN 0x400000U
#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */ #define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */ #define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */ #define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */ #define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */ #define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */
/* 0x8000000 unused */ /* 0x8000000U unused */
/* 0x10000000 unused */ /* 0x10000000U unused */
/* 0x20000000 unused */ /* 0x20000000U unused */
/* 0x40000000 unused */ /* 0x40000000U unused */
/* Flags for png_create_struct */ /* Flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001 #define PNG_STRUCT_PNG 0x0001U
#define PNG_STRUCT_INFO 0x0002 #define PNG_STRUCT_INFO 0x0002U
/* Flags for the png_ptr->flags rather than declaring a byte for each one */ /* Flags for the png_ptr->flags rather than declaring a byte for each one */
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U
#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */ #define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */
/* 0x0004 unused */ /* 0x0004U unused */
#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */ #define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */
/* 0x0010 unused */ /* 0x0010U unused */
/* 0x0020 unused */ /* 0x0020U unused */
#define PNG_FLAG_ROW_INIT 0x0040 #define PNG_FLAG_ROW_INIT 0x0040U
#define PNG_FLAG_FILLER_AFTER 0x0080 #define PNG_FLAG_FILLER_AFTER 0x0080U
#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 #define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 #define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 #define PNG_FLAG_CRC_CRITICAL_USE 0x0400U
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 #define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U
#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */ #define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */
#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */ #define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */
#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */ #define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */
/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */ /* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */
/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */ /* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000 #define PNG_FLAG_LIBRARY_MISMATCH 0x20000U
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000 #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000 #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */ #define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */
#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */ #define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */
#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */ #define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */
/* 0x800000 unused */ /* 0x800000U unused */
/* 0x1000000 unused */ /* 0x1000000U unused */
/* 0x2000000 unused */ /* 0x2000000U unused */
/* 0x4000000 unused */ /* 0x4000000U unused */
/* 0x8000000 unused */ /* 0x8000000U unused */
/* 0x10000000 unused */ /* 0x10000000U unused */
/* 0x20000000 unused */ /* 0x20000000U unused */
/* 0x40000000 unused */ /* 0x40000000U unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN) PNG_FLAG_CRC_ANCILLARY_NOWARN)
@ -637,8 +737,26 @@
/* Added to libpng-1.2.6 JB */ /* Added to libpng-1.2.6 JB */
#define PNG_ROWBYTES(pixel_bits, width) \ #define PNG_ROWBYTES(pixel_bits, width) \
((pixel_bits) >= 8 ? \ ((pixel_bits) >= 8 ? \
((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \
(( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 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_OUT_OF_RANGE returns true if value is outside the range /* PNG_OUT_OF_RANGE returns true if value is outside the range
* ideal-delta..ideal+delta. Each argument is evaluated twice. * ideal-delta..ideal+delta. Each argument is evaluated twice.
@ -733,6 +851,7 @@
#define png_PLTE PNG_U32( 80, 76, 84, 69) #define png_PLTE PNG_U32( 80, 76, 84, 69)
#define png_bKGD PNG_U32( 98, 75, 71, 68) #define png_bKGD PNG_U32( 98, 75, 71, 68)
#define png_cHRM PNG_U32( 99, 72, 82, 77) #define png_cHRM PNG_U32( 99, 72, 82, 77)
#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ #define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
#define png_gAMA PNG_U32(103, 65, 77, 65) #define png_gAMA PNG_U32(103, 65, 77, 65)
#define png_gIFg PNG_U32(103, 73, 70, 103) #define png_gIFg PNG_U32(103, 73, 70, 103)
@ -807,7 +926,7 @@
* PNG files the -I directives must match. * PNG files the -I directives must match.
* *
* The most likely explanation is that you passed a -I in CFLAGS. This will * The most likely explanation is that you passed a -I in CFLAGS. This will
* not work; all the preprocessor directories and in particular all the -I * not work; all the preprocessor directives and in particular all the -I
* directives must be in CPPFLAGS. * directives must be in CPPFLAGS.
*/ */
#endif #endif
@ -936,15 +1055,15 @@ PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
*/ */
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
png_bytep data, png_size_t length),PNG_EMPTY); png_bytep data, size_t length),PNG_EMPTY);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
png_bytep buffer, png_size_t length),PNG_EMPTY); png_bytep buffer, size_t length),PNG_EMPTY);
#endif #endif
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
png_bytep data, png_size_t length),PNG_EMPTY); png_bytep data, size_t length),PNG_EMPTY);
#ifdef PNG_WRITE_FLUSH_SUPPORTED #ifdef PNG_WRITE_FLUSH_SUPPORTED
# ifdef PNG_STDIO_SUPPORTED # ifdef PNG_STDIO_SUPPORTED
@ -958,7 +1077,7 @@ PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
/* Write the "data" buffer to whatever output you are using */ /* Write the "data" buffer to whatever output you are using */
PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
png_const_bytep data, png_size_t length),PNG_EMPTY); png_const_bytep data, size_t length),PNG_EMPTY);
/* Read and check the PNG file signature */ /* Read and check the PNG file signature */
PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
@ -970,7 +1089,7 @@ PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
/* Read data from whatever input you are using into the "data" buffer */ /* 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, PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
png_size_t length),PNG_EMPTY); size_t length),PNG_EMPTY);
/* Read bytes into buf, and update png_ptr->crc */ /* Read bytes into buf, and update png_ptr->crc */
PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
@ -988,7 +1107,7 @@ PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
* since this is the maximum buffer size we can specify. * since this is the maximum buffer size we can specify.
*/ */
PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
png_const_bytep ptr, png_size_t length),PNG_EMPTY); png_const_bytep ptr, size_t length),PNG_EMPTY);
#ifdef PNG_WRITE_FLUSH_SUPPORTED #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);
@ -1025,7 +1144,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
#ifdef PNG_WRITE_cHRM_SUPPORTED #ifdef PNG_WRITE_cHRM_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
const png_xy *xy), PNG_EMPTY); const png_xy *xy), PNG_EMPTY);
/* The xy value must have been previously validated */ /* The xy value must have been previously validated */
#endif #endif
#ifdef PNG_WRITE_sRGB_SUPPORTED #ifdef PNG_WRITE_sRGB_SUPPORTED
@ -1033,6 +1152,11 @@ PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
int intent),PNG_EMPTY); int intent),PNG_EMPTY);
#endif #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);
#endif
#ifdef PNG_WRITE_iCCP_SUPPORTED #ifdef PNG_WRITE_iCCP_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
png_const_charp name, png_const_bytep profile), PNG_EMPTY); png_const_charp name, png_const_bytep profile), PNG_EMPTY);
@ -1066,7 +1190,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
/* Chunks that have keywords */ /* Chunks that have keywords */
#ifdef PNG_WRITE_tEXt_SUPPORTED #ifdef PNG_WRITE_tEXt_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, 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); png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY);
#endif #endif
#ifdef PNG_WRITE_zTXt_SUPPORTED #ifdef PNG_WRITE_zTXt_SUPPORTED
@ -1174,6 +1298,7 @@ PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop 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); 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_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_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
@ -1188,6 +1313,56 @@ 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); 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 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); row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_MIPS_MSA_OPT > 0
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_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
/* Choose the best filter to use and filter the row data */ /* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
@ -1215,7 +1390,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
/* Initialize the row buffers, etc. */ /* Initialize the row buffers, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
#if PNG_ZLIB_VERNUM >= 0x1240 #if ZLIB_VERNUM >= 0x1240
PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush), PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
PNG_EMPTY); PNG_EMPTY);
# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) # define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
@ -1281,6 +1456,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif #endif
#ifdef PNG_READ_eXIf_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
@ -1356,9 +1536,12 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif #endif
PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
png_uint_32 chunk_name),PNG_EMPTY); png_uint_32 chunk_name),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
png_uint_32 chunk_length),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
/* This is the function that gets called for unknown chunks. The 'keep' /* This is the function that gets called for unknown chunks. The 'keep'
@ -1400,10 +1583,10 @@ 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_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
PNG_EMPTY); PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); 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_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); png_bytep buffer, size_t buffer_length),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
PNG_EMPTY); PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
@ -1413,7 +1596,7 @@ PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY); png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
png_bytep row),PNG_EMPTY); png_bytep row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY); png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
@ -1452,13 +1635,13 @@ PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY); png_inforp info_ptr), PNG_EMPTY);
/* Synchronize the info 'valid' flags with the colorspace */ /* Synchronize the info 'valid' flags with the colorspace */
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY); png_inforp info_ptr), PNG_EMPTY);
/* Copy the png_struct colorspace to the info_struct and call the above to /* 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. * synchronize the flags. Checks for NULL info_ptr and does nothing.
*/ */
#endif #endif
/* Added at libpng version 1.4.0 */ /* Added at libpng version 1.4.0 */
@ -1492,9 +1675,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
/* The 'name' is used for information only */ /* The 'name' is used for information only */
/* Routines for checking parts of an ICC profile. */ /* 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_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
png_colorspacerp colorspace, png_const_charp name, png_colorspacerp colorspace, png_const_charp name,
png_uint_32 profile_length), PNG_EMPTY); png_uint_32 profile_length), PNG_EMPTY);
#endif /* READ_iCCP */
PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
png_colorspacerp colorspace, png_const_charp name, png_colorspacerp colorspace, png_const_charp name,
png_uint_32 profile_length, png_uint_32 profile_length,
@ -1671,13 +1856,13 @@ PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
#ifdef PNG_FLOATING_POINT_SUPPORTED #ifdef PNG_FLOATING_POINT_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, 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_charp ascii, size_t size, double fp, unsigned int precision),
PNG_EMPTY); PNG_EMPTY);
#endif /* FLOATING_POINT */ #endif /* FLOATING_POINT */
#ifdef PNG_FIXED_POINT_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, 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); png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY);
#endif /* FIXED_POINT */ #endif /* FIXED_POINT */
#endif /* sCAL */ #endif /* sCAL */
@ -1770,7 +1955,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
* the problem character.) This has not been tested within libpng. * the problem character.) This has not been tested within libpng.
*/ */
PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
/* This is the same but it checks a complete string and returns true /* 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 * only if it just contains a floating point number. As of 1.5.4 this
@ -1779,7 +1964,7 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
* for negative or zero values using the sticky flag. * for negative or zero values using the sticky flag.
*/ */
PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
png_size_t size),PNG_EMPTY); size_t size),PNG_EMPTY);
#endif /* pCAL || sCAL */ #endif /* pCAL || sCAL */
#if defined(PNG_GAMMA_SUPPORTED) ||\ #if defined(PNG_GAMMA_SUPPORTED) ||\
@ -1854,7 +2039,7 @@ typedef struct png_control
png_voidp error_buf; /* Always a jmp_buf at present. */ png_voidp error_buf; /* Always a jmp_buf at present. */
png_const_bytep memory; /* Memory buffer. */ png_const_bytep memory; /* Memory buffer. */
png_size_t size; /* Size of the memory buffer. */ size_t size; /* Size of the memory buffer. */
unsigned int for_write :1; /* Otherwise it is a read structure */ unsigned int for_write :1; /* Otherwise it is a read structure */
unsigned int owned_file :1; /* We own the file in io_ptr */ unsigned int owned_file :1; /* We own the file in io_ptr */
@ -1913,13 +2098,48 @@ PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
* the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
* CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
*/ */
# if PNG_ARM_NEON_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY); (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif #endif
#if PNG_MIPS_MSA_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
(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
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
png_const_charp key, png_bytep new_key), PNG_EMPTY); 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 ^ */ /* Maintainer: Put new private prototypes here ^ */
#include "pngdebug.h" #include "pngdebug.h"

File diff suppressed because it is too large Load Diff

@ -1,10 +1,10 @@
/* pngrio.c - functions for data input /* pngrio.c - functions for data input
* *
* Last changed in libpng 1.6.17 [March 26, 2015] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -29,7 +29,7 @@
* to read more than 64K on a 16-bit machine. * to read more than 64K on a 16-bit machine.
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
{ {
png_debug1(4, "reading %d bytes", (int)length); png_debug1(4, "reading %d bytes", (int)length);
@ -47,14 +47,14 @@ png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
* than changing the library. * than changing the library.
*/ */
void PNGCBAPI void PNGCBAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
{ {
png_size_t check; size_t check;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t /* fread() returns 0 on error, so it is OK to store this in a size_t
* instead of an int, which is what fread() actually returns. * instead of an int, which is what fread() actually returns.
*/ */
check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
*/ */
void PNGAPI void PNGAPI
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, 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) if (png_ptr == NULL)
return; return;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,10 +1,10 @@
/* pngset.c - storage of image information into info struct /* pngset.c - storage of image information into info struct
* *
* Last changed in libpng 1.6.23 [June 9, 2016] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2016 Glenn Randers-Pehrson * Copyright (c) 1998-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -104,14 +104,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) double green_x, double green_y, double blue_x, double blue_y)
{ {
png_set_cHRM_fixed(png_ptr, info_ptr, png_set_cHRM_fixed(png_ptr, info_ptr,
png_fixed(png_ptr, white_x, "cHRM White X"), png_fixed(png_ptr, white_x, "cHRM White X"),
png_fixed(png_ptr, white_y, "cHRM White Y"), png_fixed(png_ptr, white_y, "cHRM White Y"),
png_fixed(png_ptr, red_x, "cHRM Red X"), png_fixed(png_ptr, red_x, "cHRM Red X"),
png_fixed(png_ptr, red_y, "cHRM Red Y"), png_fixed(png_ptr, red_y, "cHRM Red Y"),
png_fixed(png_ptr, green_x, "cHRM Green X"), png_fixed(png_ptr, green_x, "cHRM Green X"),
png_fixed(png_ptr, green_y, "cHRM Green Y"), png_fixed(png_ptr, green_y, "cHRM Green Y"),
png_fixed(png_ptr, blue_x, "cHRM Blue X"), png_fixed(png_ptr, blue_x, "cHRM Blue X"),
png_fixed(png_ptr, blue_y, "cHRM Blue Y")); png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
} }
void PNGAPI void PNGAPI
@ -120,20 +120,67 @@ 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) double blue_X, double blue_Y, double blue_Z)
{ {
png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
png_fixed(png_ptr, red_X, "cHRM Red X"), png_fixed(png_ptr, red_X, "cHRM Red X"),
png_fixed(png_ptr, red_Y, "cHRM Red Y"), png_fixed(png_ptr, red_Y, "cHRM Red Y"),
png_fixed(png_ptr, red_Z, "cHRM Red Z"), png_fixed(png_ptr, red_Z, "cHRM Red Z"),
png_fixed(png_ptr, green_X, "cHRM Green X"), png_fixed(png_ptr, green_X, "cHRM Green X"),
png_fixed(png_ptr, green_Y, "cHRM Green Y"), png_fixed(png_ptr, green_Y, "cHRM Green Y"),
png_fixed(png_ptr, green_Z, "cHRM Green Z"), png_fixed(png_ptr, green_Z, "cHRM Green Z"),
png_fixed(png_ptr, blue_X, "cHRM Blue X"), png_fixed(png_ptr, blue_X, "cHRM Blue X"),
png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
} }
# endif /* FLOATING_POINT */ # endif /* FLOATING_POINT */
#endif /* cHRM */ #endif /* cHRM */
#ifdef PNG_eXIf_SUPPORTED
void PNGAPI
png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep eXIf_buf)
{
png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
PNG_UNUSED(info_ptr)
PNG_UNUSED(eXIf_buf)
}
void PNGAPI
png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
png_uint_32 num_exif, png_bytep eXIf_buf)
{
int i;
png_debug1(1, "in %s storage function", "eXIf");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (info_ptr->exif)
{
png_free(png_ptr, info_ptr->exif);
info_ptr->exif = NULL;
}
info_ptr->num_exif = num_exif;
info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
info_ptr->num_exif));
if (info_ptr->exif == NULL)
{
png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
return;
}
info_ptr->free_me |= PNG_FREE_EXIF;
for (i = 0; i < (int) info_ptr->num_exif; i++)
info_ptr->exif[i] = eXIf_buf[i];
info_ptr->valid |= PNG_INFO_eXIf;
}
#endif /* eXIf */
#ifdef PNG_gAMA_SUPPORTED #ifdef PNG_gAMA_SUPPORTED
void PNGFAPI void PNGFAPI
png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
@ -266,7 +313,7 @@ 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, png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
int nparams, png_const_charp units, png_charpp params) int nparams, png_const_charp units, png_charpp params)
{ {
png_size_t length; size_t length;
int i; int i;
png_debug1(1, "in %s storage function", "pCAL"); png_debug1(1, "in %s storage function", "pCAL");
@ -283,17 +330,29 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
/* Check that the type matches the specification. */ /* Check that the type matches the specification. */
if (type < 0 || type > 3) if (type < 0 || type > 3)
png_error(png_ptr, "Invalid pCAL equation type"); {
png_chunk_report(png_ptr, "Invalid pCAL equation type",
PNG_CHUNK_WRITE_ERROR);
return;
}
if (nparams < 0 || nparams > 255) if (nparams < 0 || nparams > 255)
png_error(png_ptr, "Invalid pCAL parameter count"); {
png_chunk_report(png_ptr, "Invalid pCAL parameter count",
PNG_CHUNK_WRITE_ERROR);
return;
}
/* Validate params[nparams] */ /* Validate params[nparams] */
for (i=0; i<nparams; ++i) for (i=0; i<nparams; ++i)
{ {
if (params[i] == NULL || if (params[i] == NULL ||
!png_check_fp_string(params[i], strlen(params[i]))) !png_check_fp_string(params[i], strlen(params[i])))
png_error(png_ptr, "Invalid format for pCAL parameter"); {
png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
PNG_CHUNK_WRITE_ERROR);
return;
}
} }
info_ptr->pcal_purpose = png_voidcast(png_charp, info_ptr->pcal_purpose = png_voidcast(png_charp,
@ -301,8 +360,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
if (info_ptr->pcal_purpose == NULL) if (info_ptr->pcal_purpose == NULL)
{ {
png_warning(png_ptr, "Insufficient memory for pCAL purpose"); png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
PNG_CHUNK_WRITE_ERROR);
return; return;
} }
@ -316,10 +375,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
length = strlen(units) + 1; length = strlen(units) + 1;
png_debug1(3, "allocating units for info (%lu bytes)", png_debug1(3, "allocating units for info (%lu bytes)",
(unsigned long)length); (unsigned long)length);
info_ptr->pcal_units = png_voidcast(png_charp, 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) if (info_ptr->pcal_units == NULL)
{ {
@ -331,7 +390,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(info_ptr->pcal_units, units, length); memcpy(info_ptr->pcal_units, units, length);
info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
(png_size_t)((nparams + 1) * (sizeof (png_charp))))); (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
if (info_ptr->pcal_params == NULL) if (info_ptr->pcal_params == NULL)
{ {
@ -340,7 +399,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
return; return;
} }
memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp))); memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
(sizeof (png_charp)));
for (i = 0; i < nparams; i++) for (i = 0; i < nparams; i++)
{ {
@ -370,7 +430,7 @@ void PNGAPI
png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
int unit, png_const_charp swidth, png_const_charp sheight) int unit, png_const_charp swidth, png_const_charp sheight)
{ {
png_size_t lengthw = 0, lengthh = 0; size_t lengthw = 0, lengthh = 0;
png_debug1(1, "in %s storage function", "sCAL"); png_debug1(1, "in %s storage function", "sCAL");
@ -398,7 +458,7 @@ 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); png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
info_ptr->scal_s_width = png_voidcast(png_charp, 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) if (info_ptr->scal_s_width == NULL)
{ {
@ -414,7 +474,7 @@ 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); png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
info_ptr->scal_s_height = png_voidcast(png_charp, 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) if (info_ptr->scal_s_height == NULL)
{ {
@ -453,9 +513,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
char sheight[PNG_sCAL_MAX_DIGITS+1]; char sheight[PNG_sCAL_MAX_DIGITS+1];
png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, 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_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); png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
} }
@ -563,7 +623,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
if (num_palette > 0) if (num_palette > 0)
memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color))); memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
(sizeof (png_color)));
info_ptr->palette = png_ptr->palette; info_ptr->palette = png_ptr->palette;
info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
@ -630,7 +691,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
{ {
png_charp new_iccp_name; png_charp new_iccp_name;
png_bytep new_iccp_profile; png_bytep new_iccp_profile;
png_size_t length; size_t length;
png_debug1(1, "in %s storage function", "iCCP"); png_debug1(1, "in %s storage function", "iCCP");
@ -648,7 +709,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
*/ */
{ {
int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
proflen, profile, info_ptr->color_type); proflen, profile, info_ptr->color_type);
png_colorspace_sync_info(png_ptr, info_ptr); png_colorspace_sync_info(png_ptr, info_ptr);
@ -673,7 +734,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(new_iccp_name, name, length); memcpy(new_iccp_name, name, length);
new_iccp_profile = png_voidcast(png_bytep, new_iccp_profile = png_voidcast(png_bytep,
png_malloc_warn(png_ptr, proflen)); png_malloc_warn(png_ptr, proflen));
if (new_iccp_profile == NULL) if (new_iccp_profile == NULL)
{ {
@ -748,14 +809,14 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
* the overflow checks. * the overflow checks.
*/ */
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
info_ptr->text, old_num_text, max_text-old_num_text, info_ptr->text, old_num_text, max_text-old_num_text,
sizeof *new_text)); sizeof *new_text));
} }
if (new_text == NULL) if (new_text == NULL)
{ {
png_chunk_report(png_ptr, "too many text chunks", png_chunk_report(png_ptr, "too many text chunks",
PNG_CHUNK_WRITE_ERROR); PNG_CHUNK_WRITE_ERROR);
return 1; return 1;
} }
@ -783,7 +844,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
{ {
png_chunk_report(png_ptr, "text compression mode is out of range", png_chunk_report(png_ptr, "text compression mode is out of range",
PNG_CHUNK_WRITE_ERROR); PNG_CHUNK_WRITE_ERROR);
continue; continue;
} }
@ -815,7 +876,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
# else /* iTXt */ # else /* iTXt */
{ {
png_chunk_report(png_ptr, "iTXt chunk not supported", png_chunk_report(png_ptr, "iTXt chunk not supported",
PNG_CHUNK_WRITE_ERROR); PNG_CHUNK_WRITE_ERROR);
continue; continue;
} }
# endif # endif
@ -844,7 +905,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
if (textp->key == NULL) if (textp->key == NULL)
{ {
png_chunk_report(png_ptr, "text chunk: out of memory", png_chunk_report(png_ptr, "text chunk: out of memory",
PNG_CHUNK_WRITE_ERROR); PNG_CHUNK_WRITE_ERROR);
return 1; return 1;
} }
@ -956,8 +1017,8 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
{ {
/* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
info_ptr->trans_alpha = png_voidcast(png_bytep, info_ptr->trans_alpha = png_voidcast(png_bytep,
png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
} }
png_ptr->trans_alpha = info_ptr->trans_alpha; png_ptr->trans_alpha = info_ptr->trans_alpha;
} }
@ -976,7 +1037,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
trans_color->green > sample_max || trans_color->green > sample_max ||
trans_color->blue > sample_max))) trans_color->blue > sample_max)))
png_warning(png_ptr, png_warning(png_ptr,
"tRNS chunk has out-of-range samples for bit_depth"); "tRNS chunk has out-of-range samples for bit_depth");
} }
#endif #endif
@ -1018,8 +1079,8 @@ png_set_sPLT(png_const_structrp png_ptr,
* overflows. Notice that the parameters are (int) and (size_t) * overflows. Notice that the parameters are (int) and (size_t)
*/ */
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
sizeof *np)); sizeof *np));
if (np == NULL) if (np == NULL)
{ {
@ -1037,7 +1098,7 @@ png_set_sPLT(png_const_structrp png_ptr,
do do
{ {
png_size_t length; size_t length;
/* Skip invalid input entries */ /* Skip invalid input entries */
if (entries->name == NULL || entries->entries == NULL) if (entries->name == NULL || entries->entries == NULL)
@ -1080,7 +1141,7 @@ png_set_sPLT(png_const_structrp png_ptr,
* checked it when doing the allocation. * checked it when doing the allocation.
*/ */
memcpy(np->entries, entries->entries, memcpy(np->entries, entries->entries,
entries->nentries * sizeof (png_sPLT_entry)); (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
/* Note that 'continue' skips the advance of the out pointer and out /* Note that 'continue' skips the advance of the out pointer and out
* count, so an invalid entry is not added. * count, so an invalid entry is not added.
@ -1088,8 +1149,9 @@ png_set_sPLT(png_const_structrp png_ptr,
info_ptr->valid |= PNG_INFO_sPLT; info_ptr->valid |= PNG_INFO_sPLT;
++(info_ptr->splt_palettes_num); ++(info_ptr->splt_palettes_num);
++np; ++np;
++entries;
} }
while (++entries, --nentries); while (--nentries);
if (nentries > 0) if (nentries > 0)
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@ -1110,10 +1172,10 @@ check_location(png_const_structrp png_ptr, int location)
{ {
/* Write struct, so unknown chunks come from the app */ /* Write struct, so unknown chunks come from the app */
png_app_warning(png_ptr, 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 */ /* Use the old behavior */
location = (png_byte)(png_ptr->mode & 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 /* This need not be an internal error - if the app calls
@ -1136,7 +1198,7 @@ check_location(png_const_structrp png_ptr, int location)
void PNGAPI void PNGAPI
png_set_unknown_chunks(png_const_structrp png_ptr, 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; png_unknown_chunkp np;
@ -1175,13 +1237,13 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
* appropriate to read or write. * appropriate to read or write.
*/ */
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
sizeof *np)); sizeof *np));
if (np == NULL) if (np == NULL)
{ {
png_chunk_report(png_ptr, "too many unknown chunks", png_chunk_report(png_ptr, "too many unknown chunks",
PNG_CHUNK_WRITE_ERROR); PNG_CHUNK_WRITE_ERROR);
return; return;
} }
@ -1210,12 +1272,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
else else
{ {
np->data = png_voidcast(png_bytep, np->data = png_voidcast(png_bytep,
png_malloc_base(png_ptr, unknowns->size)); png_malloc_base(png_ptr, unknowns->size));
if (np->data == NULL) if (np->data == NULL)
{ {
png_chunk_report(png_ptr, "unknown chunk: out of memory", 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 */ /* But just skip storing the unknown chunk */
continue; continue;
} }
@ -1249,7 +1311,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
{ {
png_app_error(png_ptr, "invalid unknown chunk location"); png_app_error(png_ptr, "invalid unknown chunk location");
/* Fake out the pre 1.6.0 behavior: */ /* Fake out the pre 1.6.0 behavior: */
if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */ if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
location = PNG_AFTER_IDAT; location = PNG_AFTER_IDAT;
else else
@ -1337,9 +1399,10 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
/* Ignore all unknown chunks and all chunks recognized by /* Ignore all unknown chunks and all chunks recognized by
* libpng except for IHDR, PLTE, tRNS, IDAT, and IEND * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
*/ */
static PNG_CONST png_byte chunks_to_ignore[] = { static const png_byte chunks_to_ignore[] = {
98, 75, 71, 68, '\0', /* bKGD */ 98, 75, 71, 68, '\0', /* bKGD */
99, 72, 82, 77, '\0', /* cHRM */ 99, 72, 82, 77, '\0', /* cHRM */
101, 88, 73, 102, '\0', /* eXIf */
103, 65, 77, 65, '\0', /* gAMA */ 103, 65, 77, 65, '\0', /* gAMA */
104, 73, 83, 84, '\0', /* hIST */ 104, 73, 83, 84, '\0', /* hIST */
105, 67, 67, 80, '\0', /* iCCP */ 105, 67, 67, 80, '\0', /* iCCP */
@ -1373,7 +1436,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
return; return;
} }
num_chunks = num_chunks_in; num_chunks = (unsigned int)num_chunks_in;
} }
old_num_chunks = png_ptr->num_chunk_list; old_num_chunks = png_ptr->num_chunk_list;
@ -1422,7 +1485,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
for (i=0; i<num_chunks; ++i) for (i=0; i<num_chunks; ++i)
{ {
old_num_chunks = add_one_chunk(new_list, old_num_chunks, old_num_chunks = add_one_chunk(new_list, old_num_chunks,
chunk_list+5*i, keep); chunk_list+5*i, keep);
} }
/* Now remove any spurious 'default' entries. */ /* Now remove any spurious 'default' entries. */
@ -1500,62 +1563,62 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
#endif #endif
void PNGAPI void PNGAPI
png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (size == 0 || size > PNG_UINT_31_MAX) if (size == 0 || size > PNG_UINT_31_MAX)
png_error(png_ptr, "invalid compression buffer size"); png_error(png_ptr, "invalid compression buffer size");
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED # ifdef PNG_SEQUENTIAL_READ_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
{ {
png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
return; return;
} }
# endif # endif
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
{
if (png_ptr->zowner != 0)
{ {
if (png_ptr->zowner != 0) png_warning(png_ptr,
{ "Compression buffer size cannot be changed because it is in use");
png_warning(png_ptr,
"Compression buffer size cannot be changed because it is in use");
return; return;
} }
#ifndef __COVERITY__ #ifndef __COVERITY__
/* Some compilers complain that this is always false. However, it /* Some compilers complain that this is always false. However, it
* can be true when integer overflow happens. * can be true when integer overflow happens.
*/ */
if (size > ZLIB_IO_MAX) if (size > ZLIB_IO_MAX)
{ {
png_warning(png_ptr, png_warning(png_ptr,
"Compression buffer size limited to system maximum"); "Compression buffer size limited to system maximum");
size = ZLIB_IO_MAX; /* must fit */ size = ZLIB_IO_MAX; /* must fit */
} }
#endif #endif
if (size < 6) if (size < 6)
{ {
/* Deflate will potentially go into an infinite loop on a SYNC_FLUSH /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
* if this is permitted. * if this is permitted.
*/ */
png_warning(png_ptr, png_warning(png_ptr,
"Compression buffer size cannot be reduced below 6"); "Compression buffer size cannot be reduced below 6");
return; return;
}
if (png_ptr->zbuffer_size != size)
{
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_ptr->zbuffer_size = (uInt)size;
}
} }
if (png_ptr->zbuffer_size != size)
{
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_ptr->zbuffer_size = (uInt)size;
}
}
# endif # endif
} }
@ -1563,7 +1626,7 @@ void PNGAPI
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
{ {
if (png_ptr != NULL && info_ptr != NULL) if (png_ptr != NULL && info_ptr != NULL)
info_ptr->valid &= ~mask; info_ptr->valid &= (unsigned int)(~mask);
} }
@ -1662,7 +1725,9 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
png_uint_32 /* PRIVATE */ png_uint_32 /* PRIVATE */
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) 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; png_const_charp orig_key = key;
#endif
png_uint_32 key_len = 0; png_uint_32 key_len = 0;
int bad_character = 0; int bad_character = 0;
int space = 1; int space = 1;
@ -1680,14 +1745,16 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
png_byte ch = (png_byte)*key++; png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
*new_key++ = ch, ++key_len, space = 0; {
*new_key++ = ch; ++key_len; space = 0;
}
else if (space == 0) else if (space == 0)
{ {
/* A space or an invalid character when one wasn't seen immediately /* A space or an invalid character when one wasn't seen immediately
* before; output just a space. * before; output just a space.
*/ */
*new_key++ = 32, ++key_len, space = 1; *new_key++ = 32; ++key_len; space = 1;
/* If the character was not a space then it is invalid. */ /* If the character was not a space then it is invalid. */
if (ch != 32) if (ch != 32)
@ -1700,7 +1767,7 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
if (key_len > 0 && space != 0) /* trailing space */ if (key_len > 0 && space != 0) /* trailing space */
{ {
--key_len, --new_key; --key_len; --new_key;
if (bad_character == 0) if (bad_character == 0)
bad_character = 32; bad_character = 32;
} }
@ -1725,7 +1792,9 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
} }
#endif /* WARNINGS */ #else /* !WARNINGS */
PNG_UNUSED(png_ptr)
#endif /* !WARNINGS */
return key_len; return key_len;
} }

@ -1,10 +1,10 @@
/* pngstruct.h - header file for PNG reference library /* pngstruct.h - header file for PNG reference library
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -47,7 +47,7 @@
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib /* 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 * 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 * 65535), this define allows us to discover how big it is, but limited by the
* maximuum for png_size_t. The value can be overriden in a library build * maximum for size_t. The value can be overridden in a library build
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably * (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) * 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.) * and may even improve performance on some systems (and degrade it on others.)
@ -214,7 +214,7 @@ struct png_struct_def
png_uint_32 height; /* height 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 num_rows; /* number of rows in current pass */
png_uint_32 usr_width; /* width of row at start of write */ png_uint_32 usr_width; /* width of row at start of write */
png_size_t rowbytes; /* size of row in bytes */ size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */ png_uint_32 row_number; /* current row in interlace pass */
png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
@ -232,7 +232,7 @@ struct png_struct_def
png_bytep try_row; /* buffer to save trial row when filtering */ png_bytep try_row; /* buffer to save trial row when filtering */
png_bytep tst_row; /* buffer to save best trial row when filtering */ png_bytep tst_row; /* buffer to save best trial row when filtering */
#endif #endif
png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ 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 idat_size; /* current IDAT size for read */
png_uint_32 crc; /* current chunk CRC value */ png_uint_32 crc; /* current chunk CRC value */
@ -249,7 +249,7 @@ struct png_struct_def
png_byte filter; /* file filter type (always 0) */ png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */ png_byte pass; /* current interlace pass (0 - 6) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
png_byte color_type; /* color type of file */ png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */ png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row: write only */ png_byte usr_bit_depth; /* bit depth of users row: write only */
@ -263,7 +263,7 @@ struct png_struct_def
/* pixel depth used for the row buffers */ /* pixel depth used for the row buffers */
png_byte transformed_pixel_depth; png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */ /* pixel depth after read/write transforms */
#if PNG_ZLIB_VERNUM >= 0x1240 #if ZLIB_VERNUM >= 0x1240
png_byte zstream_start; /* at start of an input zlib stream */ png_byte zstream_start; /* at start of an input zlib stream */
#endif /* Zlib >= 1.2.4 */ #endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
@ -307,7 +307,7 @@ struct png_struct_def
#endif #endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
png_color_8 shift; /* shift for significant bit tranformation */ png_color_8 shift; /* shift for significant bit transformation */
#endif #endif
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
@ -328,10 +328,10 @@ struct png_struct_def
png_bytep current_buffer; /* buffer for recently used data */ png_bytep current_buffer; /* buffer for recently used data */
png_uint_32 push_length; /* size of current input chunk */ png_uint_32 push_length; /* size of current input chunk */
png_uint_32 skip_length; /* bytes to skip in input data */ png_uint_32 skip_length; /* bytes to skip in input data */
png_size_t save_buffer_size; /* amount of data now in save_buffer */ size_t save_buffer_size; /* amount of data now in save_buffer */
png_size_t save_buffer_max; /* total size of save_buffer */ size_t save_buffer_max; /* total size of save_buffer */
png_size_t buffer_size; /* total amount of available input data */ size_t buffer_size; /* total amount of available input data */
png_size_t current_buffer_size; /* amount of data now in current_buffer */ size_t current_buffer_size; /* amount of data now in current_buffer */
int process_mode; /* what push library is currently doing */ int process_mode; /* what push library is currently doing */
int cur_palette; /* current push library palette index */ int cur_palette; /* current push library palette index */
@ -353,7 +353,7 @@ struct png_struct_def
/* Options */ /* Options */
#ifdef PNG_SET_OPTION_SUPPORTED #ifdef PNG_SET_OPTION_SUPPORTED
png_byte options; /* On/off state (up to 4 options) */ png_uint_32 options; /* On/off state (up to 16 options) */
#endif #endif
#if PNG_LIBPNG_VER < 10700 #if PNG_LIBPNG_VER < 10700
@ -392,6 +392,12 @@ struct png_struct_def
/* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
#endif #endif
/* New member added in libpng-1.6.36 */
#if defined(PNG_READ_EXPAND_SUPPORTED) && \
defined(PNG_ARM_NEON_IMPLEMENTATION)
png_bytep riffled_palette; /* buffer for accelerated palette expansion */
#endif
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ /* New member added in libpng-1.0.4 (renamed in 1.0.9) */
#if defined(PNG_MNG_FEATURES_SUPPORTED) #if defined(PNG_MNG_FEATURES_SUPPORTED)
/* Changed from png_byte to png_uint_32 at version 1.2.0 */ /* Changed from png_byte to png_uint_32 at version 1.2.0 */
@ -451,7 +457,7 @@ struct png_struct_def
#endif #endif
/* New member added in libpng-1.2.26 */ /* New member added in libpng-1.2.26 */
png_size_t old_big_row_buf_size; size_t old_big_row_buf_size;
#ifdef PNG_READ_SUPPORTED #ifdef PNG_READ_SUPPORTED
/* New member added in libpng-1.2.30 */ /* New member added in libpng-1.2.30 */

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

@ -1,10 +1,10 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers) /* pngtrans.c - transforms the data in a row (used by both readers and writers)
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -172,13 +172,14 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
* size! * size!
*/ */
png_app_error(png_ptr, 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; return;
} }
default: default:
png_app_error(png_ptr, png_app_error(png_ptr,
"png_set_filler: inappropriate color type"); "png_set_filler: inappropriate color type");
return; return;
} }
# else # else
@ -268,8 +269,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
if (row_info->color_type == PNG_COLOR_TYPE_GRAY) if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{ {
png_bytep rp = row; png_bytep rp = row;
png_size_t i; size_t i;
png_size_t istop = row_info->rowbytes; size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i++) for (i = 0; i < istop; i++)
{ {
@ -282,8 +283,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
row_info->bit_depth == 8) row_info->bit_depth == 8)
{ {
png_bytep rp = row; png_bytep rp = row;
png_size_t i; size_t i;
png_size_t istop = row_info->rowbytes; size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 2) for (i = 0; i < istop; i += 2)
{ {
@ -297,8 +298,8 @@ png_do_invert(png_row_infop row_info, png_bytep row)
row_info->bit_depth == 16) row_info->bit_depth == 16)
{ {
png_bytep rp = row; png_bytep rp = row;
png_size_t i; size_t i;
png_size_t istop = row_info->rowbytes; size_t istop = row_info->rowbytes;
for (i = 0; i < istop; i += 4) for (i = 0; i < istop; i += 4)
{ {
@ -344,7 +345,7 @@ png_do_swap(png_row_infop row_info, png_bytep row)
#endif #endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static PNG_CONST png_byte onebppswaptable[256] = { static const png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
@ -379,7 +380,7 @@ static PNG_CONST png_byte onebppswaptable[256] = {
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
}; };
static PNG_CONST png_byte twobppswaptable[256] = { static const png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
@ -414,7 +415,7 @@ static PNG_CONST png_byte twobppswaptable[256] = {
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
}; };
static PNG_CONST png_byte fourbppswaptable[256] = { static const png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
@ -513,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
++sp; ++sp;
else /* Skip initial channel and, for sp, the filler */ 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 */ /* For a 1 pixel wide image there is nothing to do */
while (sp < ep) while (sp < ep)
*dp++ = *sp, sp += 2; {
*dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 8; row_info->pixel_depth = 8;
} }
@ -527,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
sp += 2; sp += 2;
else /* Skip initial channel and, for sp, the filler */ else /* Skip initial channel and, for sp, the filler */
sp += 4, dp += 2; {
sp += 4; dp += 2;
}
while (sp < ep) while (sp < ep)
*dp++ = *sp++, *dp++ = *sp, sp += 3; {
*dp++ = *sp++; *dp++ = *sp; sp += 3;
}
row_info->pixel_depth = 16; row_info->pixel_depth = 16;
} }
@ -553,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
++sp; ++sp;
else /* Skip initial channels and, for sp, the filler */ 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. */ /* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep) while (sp < ep)
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2; {
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 24; row_info->pixel_depth = 24;
} }
@ -567,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */ if (at_start != 0) /* Skip initial filler */
sp += 2; sp += 2;
else /* Skip initial channels and, for sp, the filler */ else /* Skip initial channels and, for sp, the filler */
sp += 8, dp += 6; {
sp += 8; dp += 6;
}
while (sp < ep) while (sp < ep)
{ {
/* Copy 6 bytes, skip 2 */ /* Copy 6 bytes, skip 2 */
*dp++ = *sp++, *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp, sp += 3; *dp++ = *sp++; *dp++ = *sp; sp += 3;
} }
row_info->pixel_depth = 48; row_info->pixel_depth = 48;
@ -594,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
return; /* The filler channel has gone already */ return; /* The filler channel has gone already */
/* Fix the rowbytes value. */ /* Fix the rowbytes value. */
row_info->rowbytes = dp-row; row_info->rowbytes = (size_t)(dp-row);
} }
#endif #endif
@ -692,8 +707,8 @@ 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 * and this calculation is used because it avoids warnings that other
* forms produced on either GCC or MSVC. * forms produced on either GCC or MSVC.
*/ */
int padding = (-row_info->pixel_depth * row_info->width) & 7; int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
png_bytep rp = png_ptr->row_buf + row_info->rowbytes; png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
switch (row_info->bit_depth) switch (row_info->bit_depth)
{ {
@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
{ {
png_app_error(png_ptr, 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; return;
} }
#endif #endif

@ -0,0 +1,14 @@
# pngusr.dfa
#
# Build time configuration of libpng
#
# Enter build configuration options in this file
#
# Security settings: by default these limits are unset, you can change them
# here by entering the appropriate values as #defines preceded by '@' (to cause,
# them to be passed through to the build of pnglibconf.h), for example:
#
# @# define PNG_USER_WIDTH_MAX 65535
# @# define PNG_USER_HEIGHT_MAX 65535
# @# define PNG_USER_CHUNK_CACHE_MAX 256
# @# define PNG_USER_CHUNK_MALLOC_MAX 640000

@ -1,10 +1,10 @@
/* pngwio.c - functions for data output /* pngwio.c - functions for data output
* *
* Last changed in libpng 1.6.15 [November 20, 2014] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2014 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -30,12 +30,12 @@
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
{ {
/* NOTE: write_data_fn must not change the buffer! */ /* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL ) if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
length); length);
else else
png_error(png_ptr, "Call to NULL write function"); png_error(png_ptr, "Call to NULL write function");
@ -48,9 +48,9 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
* than changing the library. * than changing the library.
*/ */
void PNGCBAPI void PNGCBAPI
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_default_write_data(png_structp png_ptr, png_bytep data, size_t length)
{ {
png_size_t check; size_t check;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;

@ -1,10 +1,10 @@
/* pngwrite.c - general routines to write a PNG file /* pngwrite.c - general routines to write a PNG file
* *
* Last changed in libpng 1.6.19 [November 12, 2015] * Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -22,7 +22,7 @@
/* Write out all the unknown chunks for the current given location */ /* Write out all the unknown chunks for the current given location */
static void static void
write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, 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 != 0)
{ {
@ -148,11 +148,11 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
# ifdef PNG_WRITE_sRGB_SUPPORTED # ifdef PNG_WRITE_sRGB_SUPPORTED
if ((info_ptr->valid & PNG_INFO_sRGB) != 0) if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
png_app_warning(png_ptr, png_app_warning(png_ptr,
"profile matches sRGB but writing iCCP instead"); "profile matches sRGB but writing iCCP instead");
# endif # endif
png_write_iCCP(png_ptr, info_ptr->iccp_name, png_write_iCCP(png_ptr, info_ptr->iccp_name,
info_ptr->iccp_profile); info_ptr->iccp_profile);
} }
# ifdef PNG_WRITE_sRGB_SUPPORTED # ifdef PNG_WRITE_sRGB_SUPPORTED
else else
@ -237,6 +237,11 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
#endif #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);
#endif
#ifdef PNG_WRITE_hIST_SUPPORTED #ifdef PNG_WRITE_hIST_SUPPORTED
if ((info_ptr->valid & PNG_INFO_hIST) != 0) if ((info_ptr->valid & PNG_INFO_hIST) != 0)
png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
@ -383,7 +388,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
for (i = 0; i < info_ptr->num_text; i++) for (i = 0; i < info_ptr->num_text; i++)
{ {
png_debug2(2, "Writing trailer text chunk %d, type %d", 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? */ /* An internationalized chunk? */
if (info_ptr->text[i].compression > 0) if (info_ptr->text[i].compression > 0)
{ {
@ -432,6 +437,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
} }
} }
#endif #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);
#endif
#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
#endif #endif
@ -458,7 +469,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_CONVERT_tIME_SUPPORTED #ifdef PNG_CONVERT_tIME_SUPPORTED
void PNGAPI void PNGAPI
png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime)
{ {
png_debug(1, "in png_convert_from_struct_tm"); png_debug(1, "in png_convert_from_struct_tm");
@ -666,9 +677,9 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{ {
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); 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 red = (png_uint_32)((s0 - s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
*(rp ) = (png_byte)(red >> 8); *(rp ) = (png_byte)(red >> 8);
@ -693,7 +704,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
return; return;
png_debug2(1, "in png_write_row (row %u, pass %d)", png_debug2(1, "in png_write_row (row %u, pass %d)",
png_ptr->row_number, png_ptr->pass); png_ptr->row_number, png_ptr->pass);
/* Initialize transformations and other stuff if first time */ /* Initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0) if (png_ptr->row_number == 0 && png_ptr->pass == 0)
@ -901,7 +912,7 @@ png_set_flush(png_structrp png_ptr, int nrows)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
} }
/* Flush the current output buffers now */ /* Flush the current output buffers now */
@ -1007,8 +1018,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
case 5: case 5:
case 6: case 6:
case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
/* FALL THROUGH */
#endif /* WRITE_FILTER */ #endif /* WRITE_FILTER */
/* FALLTHROUGH */
case PNG_FILTER_VALUE_NONE: case PNG_FILTER_VALUE_NONE:
png_ptr->do_filter = PNG_FILTER_NONE; break; png_ptr->do_filter = PNG_FILTER_NONE; break;
@ -1069,7 +1080,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
* is not available so the filter can't be used. Just warn here. * is not available so the filter can't be used. Just warn here.
*/ */
png_app_warning(png_ptr, png_app_warning(png_ptr,
"png_set_filter: UP/AVG/PAETH cannot be added after start"); "png_set_filter: UP/AVG/PAETH cannot be added after start");
filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
} }
@ -1095,13 +1106,13 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
if (png_ptr->try_row == NULL) if (png_ptr->try_row == NULL)
png_ptr->try_row = png_voidcast(png_bytep, png_ptr->try_row = png_voidcast(png_bytep,
png_malloc(png_ptr, buf_size)); png_malloc(png_ptr, buf_size));
if (num_filters > 1) if (num_filters > 1)
{ {
if (png_ptr->tst_row == NULL) if (png_ptr->tst_row == NULL)
png_ptr->tst_row = png_voidcast(png_bytep, png_ptr->tst_row = png_voidcast(png_bytep,
png_malloc(png_ptr, buf_size)); png_malloc(png_ptr, buf_size));
} }
} }
png_ptr->do_filter = (png_byte)filters; png_ptr->do_filter = (png_byte)filters;
@ -1525,7 +1536,8 @@ png_write_image_16bit(png_voidp argument)
display->first_row); display->first_row);
png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
png_uint_16p row_end; png_uint_16p row_end;
const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
3 : 1;
int aindex = 0; int aindex = 0;
png_uint_32 y = image->height; png_uint_32 y = image->height;
@ -1539,9 +1551,9 @@ png_write_image_16bit(png_voidp argument)
++output_row; ++output_row;
} }
else else
aindex = channels; aindex = (int)channels;
# else # else
aindex = channels; aindex = (int)channels;
# endif # endif
} }
@ -1554,14 +1566,14 @@ png_write_image_16bit(png_voidp argument)
*/ */
row_end = output_row + image->width * (channels+1); row_end = output_row + image->width * (channels+1);
while (y-- > 0) for (; y > 0; --y)
{ {
png_const_uint_16p in_ptr = input_row; png_const_uint_16p in_ptr = input_row;
png_uint_16p out_ptr = output_row; png_uint_16p out_ptr = output_row;
while (out_ptr < row_end) while (out_ptr < row_end)
{ {
const png_uint_16 alpha = in_ptr[aindex]; png_uint_16 alpha = in_ptr[aindex];
png_uint_32 reciprocal = 0; png_uint_32 reciprocal = 0;
int c; int c;
@ -1575,7 +1587,7 @@ png_write_image_16bit(png_voidp argument)
if (alpha > 0 && alpha < 65535) if (alpha > 0 && alpha < 65535)
reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
c = channels; c = (int)channels;
do /* always at least one channel */ do /* always at least one channel */
{ {
png_uint_16 component = *in_ptr++; png_uint_16 component = *in_ptr++;
@ -1610,7 +1622,7 @@ png_write_image_16bit(png_voidp argument)
} }
png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16)); input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
} }
return 1; return 1;
@ -1624,11 +1636,11 @@ png_write_image_16bit(png_voidp argument)
* calculation can be done to 15 bits of accuracy; however, the output needs to * 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. * 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 static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha, 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 /* 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 * is represented as some other value there is more likely to be a
@ -1683,7 +1695,8 @@ png_write_image_8bit(png_voidp argument)
display->first_row); display->first_row);
png_bytep output_row = png_voidcast(png_bytep, display->local_row); png_bytep output_row = png_voidcast(png_bytep, display->local_row);
png_uint_32 y = image->height; png_uint_32 y = image->height;
const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
3 : 1;
if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
{ {
@ -1700,12 +1713,12 @@ png_write_image_8bit(png_voidp argument)
else else
# endif # endif
aindex = channels; aindex = (int)channels;
/* Use row_end in place of a loop counter: */ /* Use row_end in place of a loop counter: */
row_end = output_row + image->width * (channels+1); row_end = output_row + image->width * (channels+1);
while (y-- > 0) for (; y > 0; --y)
{ {
png_const_uint_16p in_ptr = input_row; png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row; png_bytep out_ptr = output_row;
@ -1723,7 +1736,7 @@ png_write_image_8bit(png_voidp argument)
if (alphabyte > 0 && alphabyte < 255) if (alphabyte > 0 && alphabyte < 255)
reciprocal = UNP_RECIPROCAL(alpha); reciprocal = UNP_RECIPROCAL(alpha);
c = channels; c = (int)channels;
do /* always at least one channel */ do /* always at least one channel */
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
while (--c > 0); while (--c > 0);
@ -1735,7 +1748,7 @@ png_write_image_8bit(png_voidp argument)
png_write_row(png_ptr, png_voidcast(png_const_bytep, png_write_row(png_ptr, png_voidcast(png_const_bytep,
display->local_row)); display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16)); input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
} /* while y */ } /* while y */
} }
@ -1746,7 +1759,7 @@ png_write_image_8bit(png_voidp argument)
*/ */
png_bytep row_end = output_row + image->width * channels; png_bytep row_end = output_row + image->width * channels;
while (y-- > 0) for (; y > 0; --y)
{ {
png_const_uint_16p in_ptr = input_row; png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row; png_bytep out_ptr = output_row;
@ -1760,7 +1773,7 @@ png_write_image_8bit(png_voidp argument)
} }
png_write_row(png_ptr, output_row); png_write_row(png_ptr, output_row);
input_row += display->row_bytes/(sizeof (png_uint_16)); input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
} }
} }
@ -1770,25 +1783,25 @@ png_write_image_8bit(png_voidp argument)
static void static void
png_image_set_PLTE(png_image_write_control *display) png_image_set_PLTE(png_image_write_control *display)
{ {
const png_imagep image = display->image; png_imagep image = display->image;
const void *cmap = display->colormap; const void *cmap = display->colormap;
const int entries = image->colormap_entries > 256 ? 256 : int entries = image->colormap_entries > 256 ? 256 :
(int)image->colormap_entries; (int)image->colormap_entries;
/* NOTE: the caller must check for cmap != NULL and entries != 0 */ /* NOTE: the caller must check for cmap != NULL and entries != 0 */
const png_uint_32 format = image->format; png_uint_32 format = image->format;
const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ # if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
(format & PNG_FORMAT_FLAG_ALPHA) != 0; (format & PNG_FORMAT_FLAG_ALPHA) != 0;
# else # else
# define afirst 0 # define afirst 0
# endif # endif
# ifdef PNG_FORMAT_BGR_SUPPORTED # ifdef PNG_FORMAT_BGR_SUPPORTED
const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
# else # else
# define bgr 0 # define bgr 0
# endif # endif
@ -1809,7 +1822,7 @@ png_image_set_PLTE(png_image_write_control *display)
{ {
png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap); png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
entry += i * channels; entry += (unsigned int)i * channels;
if ((channels & 1) != 0) /* no alpha */ if ((channels & 1) != 0) /* no alpha */
{ {
@ -1848,16 +1861,16 @@ png_image_set_PLTE(png_image_write_control *display)
if (channels >= 3) /* RGB */ if (channels >= 3) /* RGB */
{ {
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
alpha, reciprocal); alpha, reciprocal);
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
reciprocal); reciprocal);
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
reciprocal); reciprocal);
} }
else /* gray */ else /* gray */
palette[i].blue = palette[i].red = palette[i].green = palette[i].blue = palette[i].red = palette[i].green =
png_unpremultiply(entry[afirst], alpha, reciprocal); png_unpremultiply(entry[afirst], alpha, reciprocal);
} }
} }
@ -1865,7 +1878,7 @@ png_image_set_PLTE(png_image_write_control *display)
{ {
png_const_bytep entry = png_voidcast(png_const_bytep, cmap); png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
entry += i * channels; entry += (unsigned int)i * channels;
switch (channels) switch (channels)
{ {
@ -1873,7 +1886,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[afirst ? 0 : 3]; tRNS[i] = entry[afirst ? 0 : 3];
if (tRNS[i] < 255) if (tRNS[i] < 255)
num_trans = i+1; num_trans = i+1;
/* FALL THROUGH */ /* FALLTHROUGH */
case 3: case 3:
palette[i].blue = entry[afirst + (2 ^ bgr)]; palette[i].blue = entry[afirst + (2 ^ bgr)];
palette[i].green = entry[afirst + 1]; palette[i].green = entry[afirst + 1];
@ -1884,7 +1897,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[1 ^ afirst]; tRNS[i] = entry[1 ^ afirst];
if (tRNS[i] < 255) if (tRNS[i] < 255)
num_trans = i+1; num_trans = i+1;
/* FALL THROUGH */ /* FALLTHROUGH */
case 1: case 1:
palette[i].blue = palette[i].red = palette[i].green = palette[i].blue = palette[i].red = palette[i].green =
entry[afirst]; entry[afirst];
@ -1904,20 +1917,20 @@ png_image_set_PLTE(png_image_write_control *display)
# endif # endif
png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
entries); entries);
if (num_trans > 0) if (num_trans > 0)
png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
num_trans, NULL); num_trans, NULL);
image->colormap_entries = entries; image->colormap_entries = (png_uint_32)entries;
} }
static int static int
png_image_write_main(png_voidp argument) png_image_write_main(png_voidp argument)
{ {
png_image_write_control *display = png_voidcast(png_image_write_control*, png_image_write_control *display = png_voidcast(png_image_write_control*,
argument); argument);
png_imagep image = display->image; png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr; png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr; png_inforp info_ptr = image->opaque->info_ptr;
@ -1927,7 +1940,7 @@ png_image_write_main(png_voidp argument)
int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
int write_16bit = linear && !colormap && (display->convert_to_8bit == 0); int write_16bit = linear && (display->convert_to_8bit == 0);
# ifdef PNG_BENIGN_ERRORS_SUPPORTED # ifdef PNG_BENIGN_ERRORS_SUPPORTED
/* Make sure we error out on any bad situation */ /* Make sure we error out on any bad situation */
@ -1938,21 +1951,21 @@ png_image_write_main(png_voidp argument)
* and total image size to ensure that they are within the system limits. * and total image size to ensure that they are within the system limits.
*/ */
{ {
const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */ if (image->width <= 0x7fffffffU/channels) /* no overflow */
{ {
png_uint_32 check; png_uint_32 check;
const png_uint_32 png_row_stride = image->width * channels; png_uint_32 png_row_stride = image->width * channels;
if (display->row_stride == 0) if (display->row_stride == 0)
display->row_stride = (png_int_32)/*SAFE*/png_row_stride; display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
if (display->row_stride < 0) if (display->row_stride < 0)
check = -display->row_stride; check = (png_uint_32)(-display->row_stride);
else else
check = display->row_stride; check = (png_uint_32)display->row_stride;
if (check >= png_row_stride) if (check >= png_row_stride)
{ {
@ -1960,7 +1973,7 @@ png_image_write_main(png_voidp argument)
* limits the whole image size to 32 bits for API compatibility with * limits the whole image size to 32 bits for API compatibility with
* the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
*/ */
if (image->height > 0xFFFFFFFF/png_row_stride) if (image->height > 0xffffffffU/png_row_stride)
png_error(image->opaque->png_ptr, "memory image too large"); png_error(image->opaque->png_ptr, "memory image too large");
} }
@ -1980,24 +1993,24 @@ png_image_write_main(png_voidp argument)
png_uint_32 entries = image->colormap_entries; png_uint_32 entries = image->colormap_entries;
png_set_IHDR(png_ptr, info_ptr, image->width, image->height, png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_image_set_PLTE(display); png_image_set_PLTE(display);
} }
else else
png_error(image->opaque->png_ptr, png_error(image->opaque->png_ptr,
"no color-map for color-mapped image"); "no color-map for color-mapped image");
} }
else else
png_set_IHDR(png_ptr, info_ptr, image->width, image->height, png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
write_16bit ? 16 : 8, write_16bit ? 16 : 8,
((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* Counter-intuitively the data transformations must be called *after* /* Counter-intuitively the data transformations must be called *after*
* png_write_info, not before as in the read code, but the 'set' functions * png_write_info, not before as in the read code, but the 'set' functions
@ -2012,11 +2025,11 @@ png_image_write_main(png_voidp argument)
if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
png_set_cHRM_fixed(png_ptr, info_ptr, png_set_cHRM_fixed(png_ptr, info_ptr,
/* color x y */ /* color x y */
/* white */ 31270, 32900, /* white */ 31270, 32900,
/* red */ 64000, 33000, /* red */ 64000, 33000,
/* green */ 30000, 60000, /* green */ 30000, 60000,
/* blue */ 15000, 6000 /* blue */ 15000, 6000
); );
} }
@ -2039,7 +2052,7 @@ png_image_write_main(png_voidp argument)
*/ */
if (write_16bit != 0) if (write_16bit != 0)
{ {
PNG_CONST png_uint_16 le = 0x0001; png_uint_16 le = 0x0001;
if ((*(png_const_bytep) & le) != 0) if ((*(png_const_bytep) & le) != 0)
png_set_swap(png_ptr); png_set_swap(png_ptr);
@ -2110,7 +2123,7 @@ png_image_write_main(png_voidp argument)
(colormap == 0 && display->convert_to_8bit != 0)) (colormap == 0 && display->convert_to_8bit != 0))
{ {
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, 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; int result;
display->local_row = row; display->local_row = row;
@ -2136,7 +2149,7 @@ png_image_write_main(png_voidp argument)
ptrdiff_t row_bytes = display->row_bytes; ptrdiff_t row_bytes = display->row_bytes;
png_uint_32 y = image->height; png_uint_32 y = image->height;
while (y-- > 0) for (; y > 0; --y)
{ {
png_write_row(png_ptr, row); png_write_row(png_ptr, row);
row += row_bytes; row += row_bytes;
@ -2149,12 +2162,11 @@ png_image_write_main(png_voidp argument)
static void (PNGCBAPI static void (PNGCBAPI
image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size)
png_size_t size)
{ {
png_image_write_control *display = png_voidcast(png_image_write_control*, png_image_write_control *display = png_voidcast(png_image_write_control*,
png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
const png_alloc_size_t ob = display->output_bytes; png_alloc_size_t ob = display->output_bytes;
/* Check for overflow; this should never happen: */ /* Check for overflow; this should never happen: */
if (size <= ((png_alloc_size_t)-1) - ob) if (size <= ((png_alloc_size_t)-1) - ob)
@ -2184,22 +2196,22 @@ static int
png_image_write_memory(png_voidp argument) png_image_write_memory(png_voidp argument)
{ {
png_image_write_control *display = png_voidcast(png_image_write_control*, png_image_write_control *display = png_voidcast(png_image_write_control*,
argument); argument);
/* The rest of the memory-specific init and write_main in an error protected /* 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 * environment. This case needs to use callbacks for the write operations
* since libpng has no built in support for writing to memory. * since libpng has no built in support for writing to memory.
*/ */
png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
image_memory_write, image_memory_flush); image_memory_write, image_memory_flush);
return png_image_write_main(display); return png_image_write_main(display);
} }
int PNGAPI int PNGAPI
png_image_write_to_memory(png_imagep image, void *memory, png_image_write_to_memory(png_imagep image, void *memory,
png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, png_alloc_size_t * PNG_RESTRICT memory_bytes, 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)
{ {
/* Write the image to the given buffer, or count the bytes if it is NULL */ /* Write the image to the given buffer, or count the bytes if it is NULL */
if (image != NULL && image->version == PNG_IMAGE_VERSION) if (image != NULL && image->version == PNG_IMAGE_VERSION)
@ -2251,12 +2263,12 @@ png_image_write_to_memory(png_imagep image, void *memory,
else else
return png_image_error(image, return png_image_error(image,
"png_image_write_to_memory: invalid argument"); "png_image_write_to_memory: invalid argument");
} }
else if (image != NULL) else if (image != NULL)
return png_image_error(image, return png_image_error(image,
"png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
else else
return 0; return 0;
@ -2265,7 +2277,7 @@ png_image_write_to_memory(png_imagep image, void *memory,
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
int PNGAPI int PNGAPI
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, 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)
{ {
/* Write the image to the given (FILE*). */ /* Write the image to the given (FILE*). */
if (image != NULL && image->version == PNG_IMAGE_VERSION) if (image != NULL && image->version == PNG_IMAGE_VERSION)
@ -2301,12 +2313,12 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
else else
return png_image_error(image, return png_image_error(image,
"png_image_write_to_stdio: invalid argument"); "png_image_write_to_stdio: invalid argument");
} }
else if (image != NULL) else if (image != NULL)
return png_image_error(image, return png_image_error(image,
"png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
else else
return 0; return 0;
@ -2314,8 +2326,8 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
int PNGAPI int PNGAPI
png_image_write_to_file(png_imagep image, const char *file_name, png_image_write_to_file(png_imagep image, const char *file_name,
int convert_to_8bit, const void *buffer, png_int_32 row_stride, int convert_to_8bit, const void *buffer, png_int_32 row_stride,
const void *colormap) const void *colormap)
{ {
/* Write the image to the named file. */ /* Write the image to the named file. */
if (image != NULL && image->version == PNG_IMAGE_VERSION) if (image != NULL && image->version == PNG_IMAGE_VERSION)
@ -2327,7 +2339,7 @@ png_image_write_to_file(png_imagep image, const char *file_name,
if (fp != NULL) if (fp != NULL)
{ {
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
row_stride, colormap) != 0) row_stride, colormap) != 0)
{ {
int error; /* from fflush/fclose */ int error; /* from fflush/fclose */
@ -2368,12 +2380,12 @@ png_image_write_to_file(png_imagep image, const char *file_name,
else else
return png_image_error(image, return png_image_error(image,
"png_image_write_to_file: invalid argument"); "png_image_write_to_file: invalid argument");
} }
else if (image != NULL) else if (image != NULL)
return png_image_error(image, return png_image_error(image,
"png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
else else
return 0; return 0;

@ -1,10 +1,10 @@
/* pngwtran.c - transforms the data in a row for PNG writers /* pngwtran.c - transforms the data in a row for PNG writers
* *
* Last changed in libpng 1.6.18 [July 23, 2015] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -177,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{ {
int shift_start[4], shift_dec[4]; int shift_start[4], shift_dec[4];
int channels = 0; unsigned int channels = 0;
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
{ {
@ -212,9 +212,9 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->bit_depth < 8) if (row_info->bit_depth < 8)
{ {
png_bytep bp = row; png_bytep bp = row;
png_size_t i; size_t i;
unsigned int mask; unsigned int mask;
png_size_t row_bytes = row_info->rowbytes; size_t row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2) if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55; mask = 0x55;
@ -254,8 +254,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
for (i = 0; i < istop; i++, bp++) for (i = 0; i < istop; i++, bp++)
{ {
unsigned int c = i%channels;
const unsigned int c = i%channels;
int j; int j;
unsigned int v, out; unsigned int v, out;
@ -283,7 +282,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
for (bp = row, i = 0; i < istop; i++) for (bp = row, i = 0; i < istop; i++)
{ {
const unsigned int c = i%channels; unsigned int c = i%channels;
int j; int j;
unsigned int value, v; unsigned int value, v;
@ -514,7 +513,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
(png_ptr, /* png_ptr */ (png_ptr, /* png_ptr */
row_info, /* row_info: */ row_info, /* row_info: */
/* png_uint_32 width; width of row */ /* png_uint_32 width; width of row */
/* png_size_t rowbytes; number of bytes in row */ /* size_t rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */ /* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */ /* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */ /* png_byte channels; number of channels (1-4) */
@ -525,7 +524,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_FILLER_SUPPORTED #ifdef PNG_WRITE_FILLER_SUPPORTED
if ((png_ptr->transformations & PNG_FILLER) != 0) if ((png_ptr->transformations & PNG_FILLER) != 0)
png_do_strip_channel(row_info, png_ptr->row_buf + 1, png_do_strip_channel(row_info, png_ptr->row_buf + 1,
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif #endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
@ -549,7 +548,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_SHIFT_SUPPORTED #ifdef PNG_WRITE_SHIFT_SUPPORTED
if ((png_ptr->transformations & PNG_SHIFT) != 0) if ((png_ptr->transformations & PNG_SHIFT) != 0)
png_do_shift(row_info, png_ptr->row_buf + 1, png_do_shift(row_info, png_ptr->row_buf + 1,
&(png_ptr->shift)); &(png_ptr->shift));
#endif #endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED

@ -1,10 +1,10 @@
/* pngwutil.c - utilities to write a PNG file /* pngwutil.c - utilities to write a PNG file
* *
* Last changed in libpng 1.6.22 [May 26, 2016] * Copyright (c) 2018 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * Copyright (c) 1996-1997 Andreas Dilger
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -59,7 +59,7 @@ png_write_sig(png_structrp png_ptr)
/* Write the rest of the 8 byte signature */ /* Write the rest of the 8 byte signature */
png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
(png_size_t)(8 - png_ptr->sig_bytes)); (size_t)(8 - png_ptr->sig_bytes));
if (png_ptr->sig_bytes < 3) if (png_ptr->sig_bytes < 3)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
@ -124,8 +124,7 @@ png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
* given to png_write_chunk_header(). * given to png_write_chunk_header().
*/ */
void PNGAPI void PNGAPI
png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length)
png_size_t length)
{ {
/* Write the data, and run the CRC over it */ /* Write the data, and run the CRC over it */
if (png_ptr == NULL) if (png_ptr == NULL)
@ -160,7 +159,7 @@ png_write_chunk_end(png_structrp png_ptr)
/* Write the crc in a single operation */ /* Write the crc in a single operation */
png_save_uint_32(buf, png_ptr->crc); png_save_uint_32(buf, png_ptr->crc);
png_write_data(png_ptr, buf, (png_size_t)4); png_write_data(png_ptr, buf, 4);
} }
/* Write a PNG chunk all at once. The type is an array of ASCII characters /* Write a PNG chunk all at once. The type is an array of ASCII characters
@ -174,7 +173,7 @@ png_write_chunk_end(png_structrp png_ptr)
*/ */
static void static void
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
png_const_bytep data, png_size_t length) png_const_bytep data, size_t length)
{ {
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
@ -191,10 +190,10 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
/* This is the API that calls the internal function above. */ /* This is the API that calls the internal function above. */
void PNGAPI void PNGAPI
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
png_const_bytep data, png_size_t length) png_const_bytep data, size_t length)
{ {
png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, 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, /* This is used below to find the size of an image to pass to png_deflate_claim,
@ -291,7 +290,7 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
/* Initialize the compressor for the appropriate type of compression. */ /* Initialize the compressor for the appropriate type of compression. */
static int static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, 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 (png_ptr->zowner != 0)
{ {
@ -408,7 +407,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
png_ptr->zstream.avail_out = 0; png_ptr->zstream.avail_out = 0;
/* Now initialize if required, setting the new parameters, otherwise just /* Now initialize if required, setting the new parameters, otherwise just
* to a simple reset to the previous parameters. * do a simple reset to the previous parameters.
*/ */
if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
ret = deflateReset(&png_ptr->zstream); ret = deflateReset(&png_ptr->zstream);
@ -416,7 +415,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
else else
{ {
ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
memLevel, strategy); memLevel, strategy);
if (ret == Z_OK) if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
@ -477,7 +476,7 @@ typedef struct
static void static void
png_text_compress_init(compression_state *comp, png_const_bytep input, 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 = input;
comp->input_len = input_len; comp->input_len = input_len;
@ -487,7 +486,7 @@ png_text_compress_init(compression_state *comp, png_const_bytep input,
/* Compress the data in the compression state input */ /* Compress the data in the compression state input */
static int static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, 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; int ret;
@ -579,7 +578,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
/* Compress the data */ /* Compress the data */
ret = deflate(&png_ptr->zstream, 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 /* Claw back input data that was not consumed (because avail_in is
* reset above every time round the loop). * reset above every time round the loop).
@ -675,6 +674,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
int interlace_type) int interlace_type)
{ {
png_byte buf[13]; /* Buffer to store the IHDR info */ png_byte buf[13]; /* Buffer to store the IHDR info */
int is_invalid_depth;
png_debug(1, "in png_write_IHDR"); png_debug(1, "in png_write_IHDR");
@ -700,11 +700,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break; break;
case PNG_COLOR_TYPE_RGB: case PNG_COLOR_TYPE_RGB:
is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED #ifdef PNG_WRITE_16BIT_SUPPORTED
if (bit_depth != 8 && bit_depth != 16) is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#else
if (bit_depth != 8)
#endif #endif
if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGB image"); png_error(png_ptr, "Invalid bit depth for RGB image");
png_ptr->channels = 3; png_ptr->channels = 3;
@ -726,18 +726,22 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break; break;
case PNG_COLOR_TYPE_GRAY_ALPHA: case PNG_COLOR_TYPE_GRAY_ALPHA:
if (bit_depth != 8 && bit_depth != 16) 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)
png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
png_ptr->channels = 2; png_ptr->channels = 2;
break; break;
case PNG_COLOR_TYPE_RGB_ALPHA: case PNG_COLOR_TYPE_RGB_ALPHA:
is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED #ifdef PNG_WRITE_16BIT_SUPPORTED
if (bit_depth != 8 && bit_depth != 16) is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#else
if (bit_depth != 8)
#endif #endif
if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGBA image"); png_error(png_ptr, "Invalid bit depth for RGBA image");
png_ptr->channels = 4; png_ptr->channels = 4;
@ -815,7 +819,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
buf[12] = (png_byte)interlace_type; buf[12] = (png_byte)interlace_type;
/* Write the chunk */ /* Write the chunk */
png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
if ((png_ptr->do_filter) == PNG_NO_FILTERS) if ((png_ptr->do_filter) == PNG_NO_FILTERS)
{ {
@ -884,7 +888,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
buf[0] = pal_ptr->red; buf[0] = pal_ptr->red;
buf[1] = pal_ptr->green; buf[1] = pal_ptr->green;
buf[2] = pal_ptr->blue; buf[2] = pal_ptr->blue;
png_write_chunk_data(png_ptr, buf, (png_size_t)3); png_write_chunk_data(png_ptr, buf, 3);
} }
#else #else
@ -898,7 +902,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
buf[0] = pal_ptr[i].red; buf[0] = pal_ptr[i].red;
buf[1] = pal_ptr[i].green; buf[1] = pal_ptr[i].green;
buf[2] = pal_ptr[i].blue; buf[2] = pal_ptr[i].blue;
png_write_chunk_data(png_ptr, buf, (png_size_t)3); png_write_chunk_data(png_ptr, buf, 3);
} }
#endif #endif
@ -925,7 +929,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, 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) if (png_ptr->zowner != png_IDAT)
{ {
@ -937,7 +941,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
if (png_ptr->zbuffer_list == NULL) if (png_ptr->zbuffer_list == NULL)
{ {
png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, 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; png_ptr->zbuffer_list->next = NULL;
} }
@ -998,7 +1002,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr)); optimize_cmf(data, png_image_size(png_ptr));
#endif #endif
png_write_complete_chunk(png_ptr, png_IDAT, data, size); if (size > 0)
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->zstream.next_out = data; png_ptr->zstream.next_out = data;
@ -1044,7 +1049,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr)); optimize_cmf(data, png_image_size(png_ptr));
#endif #endif
png_write_complete_chunk(png_ptr, png_IDAT, data, size); if (size > 0)
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->zstream.avail_out = 0; png_ptr->zstream.avail_out = 0;
png_ptr->zstream.next_out = NULL; png_ptr->zstream.next_out = NULL;
png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@ -1068,7 +1074,7 @@ png_write_IEND(png_structrp png_ptr)
{ {
png_debug(1, "in png_write_IEND"); png_debug(1, "in png_write_IEND");
png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); png_write_complete_chunk(png_ptr, png_IEND, NULL, 0);
png_ptr->mode |= PNG_HAVE_IEND; png_ptr->mode |= PNG_HAVE_IEND;
} }
@ -1083,7 +1089,7 @@ png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
/* file_gamma is saved in 1/100,000ths */ /* file_gamma is saved in 1/100,000ths */
png_save_uint_32(buf, (png_uint_32)file_gamma); png_save_uint_32(buf, (png_uint_32)file_gamma);
png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); png_write_complete_chunk(png_ptr, png_gAMA, buf, 4);
} }
#endif #endif
@ -1101,7 +1107,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
"Invalid sRGB rendering intent specified"); "Invalid sRGB rendering intent specified");
buf[0]=(png_byte)srgb_intent; buf[0]=(png_byte)srgb_intent;
png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); png_write_complete_chunk(png_ptr, png_sRGB, buf, 1);
} }
#endif #endif
@ -1175,8 +1181,8 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_uint_32 name_len; png_uint_32 name_len;
png_byte new_name[80]; png_byte new_name[80];
png_byte entrybuf[10]; png_byte entrybuf[10];
png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); size_t entry_size = (spalette->depth == 8 ? 6 : 10);
png_size_t palette_size = entry_size * spalette->nentries; size_t palette_size = entry_size * (size_t)spalette->nentries;
png_sPLT_entryp ep; png_sPLT_entryp ep;
#ifndef PNG_POINTER_INDEXING_SUPPORTED #ifndef PNG_POINTER_INDEXING_SUPPORTED
int i; int i;
@ -1193,10 +1199,9 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_write_chunk_header(png_ptr, png_sPLT, png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size)); (png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name, png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1));
(png_size_t)(name_len + 1));
png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); png_write_chunk_data(png_ptr, &spalette->depth, 1);
/* Loop through each palette entry, writing appropriately */ /* Loop through each palette entry, writing appropriately */
#ifdef PNG_POINTER_INDEXING_SUPPORTED #ifdef PNG_POINTER_INDEXING_SUPPORTED
@ -1258,7 +1263,7 @@ void /* PRIVATE */
png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
{ {
png_byte buf[4]; png_byte buf[4];
png_size_t size; size_t size;
png_debug(1, "in png_write_sBIT"); png_debug(1, "in png_write_sBIT");
@ -1358,7 +1363,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
/* Write the chunk out as it is */ /* Write the chunk out as it is */
png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
(png_size_t)num_trans); (size_t)num_trans);
} }
else if (color_type == PNG_COLOR_TYPE_GRAY) else if (color_type == PNG_COLOR_TYPE_GRAY)
@ -1373,7 +1378,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
} }
png_save_uint_16(buf, tran->gray); png_save_uint_16(buf, tran->gray);
png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); png_write_complete_chunk(png_ptr, png_tRNS, buf, 2);
} }
else if (color_type == PNG_COLOR_TYPE_RGB) else if (color_type == PNG_COLOR_TYPE_RGB)
@ -1389,11 +1394,11 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
#endif #endif
{ {
png_app_warning(png_ptr, 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; return;
} }
png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); png_write_complete_chunk(png_ptr, png_tRNS, buf, 6);
} }
else else
@ -1426,7 +1431,7 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
} }
buf[0] = back->index; buf[0] = back->index;
png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); png_write_complete_chunk(png_ptr, png_bKGD, buf, 1);
} }
else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
@ -1441,12 +1446,13 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
#endif #endif
{ {
png_warning(png_ptr, 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; return;
} }
png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); png_write_complete_chunk(png_ptr, png_bKGD, buf, 6);
} }
else else
@ -1460,11 +1466,33 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
} }
png_save_uint_16(buf, back->gray); png_save_uint_16(buf, back->gray);
png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); png_write_complete_chunk(png_ptr, png_bKGD, buf, 2);
} }
} }
#endif #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 #ifdef PNG_WRITE_hIST_SUPPORTED
/* Write the histogram */ /* Write the histogram */
void /* PRIVATE */ void /* PRIVATE */
@ -1489,7 +1517,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
for (i = 0; i < num_hist; i++) for (i = 0; i < num_hist; i++)
{ {
png_save_uint_16(buf, hist[i]); png_save_uint_16(buf, hist[i]);
png_write_chunk_data(png_ptr, buf, (png_size_t)2); png_write_chunk_data(png_ptr, buf, 2);
} }
png_write_chunk_end(png_ptr); png_write_chunk_end(png_ptr);
@ -1500,7 +1528,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
/* Write a tEXt chunk */ /* Write a tEXt chunk */
void /* PRIVATE */ void /* PRIVATE */
png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
png_size_t text_len) size_t text_len)
{ {
png_uint_32 key_len; png_uint_32 key_len;
png_byte new_key[80]; png_byte new_key[80];
@ -1571,7 +1599,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 */ /* Compute the compressed data; do it now for the length */
png_text_compress_init(&comp, (png_const_bytep)text, 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) if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg); png_error(png_ptr, png_ptr->zstream.msg);
@ -1597,7 +1625,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_const_charp lang, png_const_charp lang_key, png_const_charp text)
{ {
png_uint_32 key_len, prefix_len; png_uint_32 key_len, prefix_len;
png_size_t lang_len, lang_key_len; size_t lang_len, lang_key_len;
png_byte new_key[82]; png_byte new_key[82];
compression_state comp; compression_state comp;
@ -1707,7 +1735,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); png_save_int_32(buf + 4, y_offset);
buf[8] = (png_byte)unit_type; buf[8] = (png_byte)unit_type;
png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); png_write_complete_chunk(png_ptr, png_oFFs, buf, 9);
} }
#endif #endif
#ifdef PNG_WRITE_pCAL_SUPPORTED #ifdef PNG_WRITE_pCAL_SUPPORTED
@ -1718,7 +1746,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_charpp params) png_charpp params)
{ {
png_uint_32 purpose_len; png_uint_32 purpose_len;
png_size_t units_len, total_len; size_t units_len, total_len;
png_size_tp params_len; png_size_tp params_len;
png_byte buf[10]; png_byte buf[10];
png_byte new_purpose[80]; png_byte new_purpose[80];
@ -1742,7 +1770,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
total_len = purpose_len + units_len + 10; total_len = purpose_len + units_len + 10;
params_len = (png_size_tp)png_malloc(png_ptr, params_len = (png_size_tp)png_malloc(png_ptr,
(png_alloc_size_t)(nparams * (sizeof (png_size_t)))); (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t))));
/* Find the length of each parameter, making sure we don't count the /* Find the length of each parameter, making sure we don't count the
* null terminator for the last parameter. * null terminator for the last parameter.
@ -1762,8 +1790,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
png_save_int_32(buf + 4, X1); png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)type; buf[8] = (png_byte)type;
buf[9] = (png_byte)nparams; buf[9] = (png_byte)nparams;
png_write_chunk_data(png_ptr, buf, (png_size_t)10); png_write_chunk_data(png_ptr, buf, 10);
png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len);
for (i = 0; i < nparams; i++) for (i = 0; i < nparams; i++)
{ {
@ -1782,7 +1810,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
png_const_charp height) png_const_charp height)
{ {
png_byte buf[64]; png_byte buf[64];
png_size_t wlen, hlen, total_len; size_t wlen, hlen, total_len;
png_debug(1, "in png_write_sCAL_s"); png_debug(1, "in png_write_sCAL_s");
@ -1823,7 +1851,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); png_save_uint_32(buf + 4, y_pixels_per_unit);
buf[8] = (png_byte)unit_type; buf[8] = (png_byte)unit_type;
png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); png_write_complete_chunk(png_ptr, png_pHYs, buf, 9);
} }
#endif #endif
@ -1853,7 +1881,7 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
buf[5] = mod_time->minute; buf[5] = mod_time->minute;
buf[6] = mod_time->second; buf[6] = mod_time->second;
png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); png_write_complete_chunk(png_ptr, png_tIME, buf, 7);
} }
#endif #endif
@ -1865,16 +1893,16 @@ png_write_start_row(png_structrp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* 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}; static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
#endif #endif
png_alloc_size_t buf_size; png_alloc_size_t buf_size;
@ -1941,7 +1969,7 @@ png_write_start_row(png_structrp png_ptr)
*/ */
if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
png_ptr->prev_row = png_voidcast(png_bytep, png_ptr->prev_row = png_voidcast(png_bytep,
png_calloc(png_ptr, buf_size)); png_calloc(png_ptr, buf_size));
#endif /* WRITE_FILTER */ #endif /* WRITE_FILTER */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED #ifdef PNG_WRITE_INTERLACING_SUPPORTED
@ -1980,16 +2008,16 @@ png_write_finish_row(png_structrp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* 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}; static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
#endif #endif
png_debug(1, "in png_write_finish_row"); png_debug(1, "in png_write_finish_row");
@ -2043,8 +2071,8 @@ png_write_finish_row(png_structrp png_ptr)
{ {
if (png_ptr->prev_row != NULL) if (png_ptr->prev_row != NULL)
memset(png_ptr->prev_row, 0, memset(png_ptr->prev_row, 0,
(png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* PNG_ROWBYTES(png_ptr->usr_channels *
png_ptr->usr_bit_depth, png_ptr->width)) + 1); png_ptr->usr_bit_depth, png_ptr->width) + 1);
return; return;
} }
@ -2070,10 +2098,10 @@ 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 */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
png_debug(1, "in png_do_write_interlace"); png_debug(1, "in png_do_write_interlace");
@ -2100,7 +2128,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width; for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass]) i += png_pass_inc[pass])
{ {
sp = row + (png_size_t)(i >> 3); sp = row + (size_t)(i >> 3);
value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
d |= (value << shift); d |= (value << shift);
@ -2138,7 +2166,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width; for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass]) i += png_pass_inc[pass])
{ {
sp = row + (png_size_t)(i >> 2); sp = row + (size_t)(i >> 2);
value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
d |= (value << shift); d |= (value << shift);
@ -2174,7 +2202,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
for (i = png_pass_start[pass]; i < row_width; for (i = png_pass_start[pass]; i < row_width;
i += png_pass_inc[pass]) i += png_pass_inc[pass])
{ {
sp = row + (png_size_t)(i >> 1); sp = row + (size_t)(i >> 1);
value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
d |= (value << shift); d |= (value << shift);
@ -2200,7 +2228,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
png_bytep dp; png_bytep dp;
png_uint_32 i; png_uint_32 i;
png_uint_32 row_width = row_info->width; png_uint_32 row_width = row_info->width;
png_size_t pixel_bytes; size_t pixel_bytes;
/* Start at the beginning */ /* Start at the beginning */
dp = row; dp = row;
@ -2213,7 +2241,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
i += png_pass_inc[pass]) i += png_pass_inc[pass])
{ {
/* Find out where the original pixel is */ /* Find out where the original pixel is */
sp = row + (png_size_t)i * pixel_bytes; sp = row + (size_t)i * pixel_bytes;
/* Move the pixel */ /* Move the pixel */
if (dp != sp) if (dp != sp)
@ -2244,17 +2272,17 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
*/ */
static void /* PRIVATE */ static void /* PRIVATE */
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t row_bytes); size_t row_bytes);
#ifdef PNG_WRITE_FILTER_SUPPORTED #ifdef PNG_WRITE_FILTER_SUPPORTED
static png_size_t /* PRIVATE */ static size_t /* PRIVATE */
png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp,
const png_size_t row_bytes, const png_size_t lmins) size_t row_bytes, size_t lmins)
{ {
png_bytep rp, dp, lp; png_bytep rp, dp, lp;
png_size_t i; size_t i;
png_size_t sum = 0; size_t sum = 0;
int v; unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
@ -2262,14 +2290,22 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
i++, rp++, dp++) i++, rp++, dp++)
{ {
v = *dp = *rp; v = *dp = *rp;
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v; sum += (v < 128) ? v : 256 - v;
#endif
} }
for (lp = png_ptr->row_buf + 1; i < row_bytes; for (lp = png_ptr->row_buf + 1; i < row_bytes;
i++, rp++, lp++, dp++) i++, rp++, lp++, dp++)
{ {
v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 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; sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */ if (sum > lmins) /* We are already worse, don't continue. */
break; break;
@ -2278,14 +2314,35 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum); return (sum);
} }
static png_size_t /* PRIVATE */ static void /* PRIVATE */
png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp,
const png_size_t lmins) 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; png_bytep rp, dp, pp;
png_size_t i; size_t i;
png_size_t sum = 0; size_t sum = 0;
int v; unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
@ -2294,7 +2351,11 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
i++, rp++, pp++, dp++) i++, rp++, pp++, dp++)
{ {
v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); 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; sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */ if (sum > lmins) /* We are already worse, don't continue. */
break; break;
@ -2302,24 +2363,43 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
return (sum); 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;
static png_size_t /* PRIVATE */ png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes, const png_size_t lmins) 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_bytep rp, dp, pp, lp;
png_uint_32 i; png_uint_32 i;
png_size_t sum = 0; size_t sum = 0;
int v; unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
pp = png_ptr->prev_row + 1; i < bpp; i++) pp = png_ptr->prev_row + 1; i < bpp; i++)
{ {
v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 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; sum += (v < 128) ? v : 256 - v;
#endif
} }
for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
@ -2327,7 +2407,11 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
& 0xff); & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v; sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */ if (sum > lmins) /* We are already worse, don't continue. */
break; break;
@ -2335,15 +2419,36 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum); 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;
static png_size_t /* PRIVATE */ png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes, const png_size_t lmins) 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; png_bytep rp, dp, pp, cp, lp;
png_size_t i; size_t i;
png_size_t sum = 0; size_t sum = 0;
int v; unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
@ -2352,7 +2457,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
{ {
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 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; sum += (v < 128) ? v : 256 - v;
#endif
} }
for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
@ -2381,7 +2490,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 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; sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */ if (sum > lmins) /* We are already worse, don't continue. */
break; break;
@ -2389,6 +2502,48 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum); 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 */ #endif /* WRITE_FILTER */
void /* PRIVATE */ void /* PRIVATE */
@ -2397,12 +2552,12 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
#ifndef PNG_WRITE_FILTER_SUPPORTED #ifndef PNG_WRITE_FILTER_SUPPORTED
png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
#else #else
png_byte filter_to_do = png_ptr->do_filter; unsigned int filter_to_do = png_ptr->do_filter;
png_bytep row_buf; png_bytep row_buf;
png_bytep best_row; png_bytep best_row;
png_uint_32 bpp; png_uint_32 bpp;
png_size_t mins; size_t mins;
png_size_t row_bytes = row_info->rowbytes; size_t row_bytes = row_info->rowbytes;
png_debug(1, "in png_write_find_filter"); png_debug(1, "in png_write_find_filter");
@ -2443,32 +2598,33 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
*/ */
best_row = png_ptr->row_buf; best_row = png_ptr->row_buf;
if (PNG_SIZE_MAX/128 <= row_bytes)
if ((filter_to_do & PNG_FILTER_NONE) != 0 && 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; png_bytep rp;
png_size_t sum = 0; size_t sum = 0;
png_size_t i; size_t i;
int v; unsigned int v;
if (PNG_SIZE_MAX/128 <= row_bytes)
{
for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
/* Check for overflow */
if (sum > PNG_SIZE_MAX/128 - 256)
break;
v = *rp;
sum += (v < 128) ? v : 256 - v;
}
}
else /* Overflow is not possible */
{ {
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; v = *rp;
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v; sum += (v < 128) ? v : 256 - v;
#endif
} }
} }
@ -2479,14 +2635,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (filter_to_do == PNG_FILTER_SUB) if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */ /* It's the only filter so no testing is needed */
{ {
(void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins); png_setup_sub_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row; best_row = png_ptr->try_row;
} }
else if ((filter_to_do & PNG_FILTER_SUB) != 0) else if ((filter_to_do & PNG_FILTER_SUB) != 0)
{ {
png_size_t sum; size_t sum;
png_size_t lmins = mins; size_t lmins = mins;
sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
@ -2505,14 +2661,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Up filter */ /* Up filter */
if (filter_to_do == PNG_FILTER_UP) if (filter_to_do == PNG_FILTER_UP)
{ {
(void) png_setup_up_row(png_ptr, row_bytes, mins); png_setup_up_row_only(png_ptr, row_bytes);
best_row = png_ptr->try_row; best_row = png_ptr->try_row;
} }
else if ((filter_to_do & PNG_FILTER_UP) != 0) else if ((filter_to_do & PNG_FILTER_UP) != 0)
{ {
png_size_t sum; size_t sum;
png_size_t lmins = mins; size_t lmins = mins;
sum = png_setup_up_row(png_ptr, row_bytes, lmins); sum = png_setup_up_row(png_ptr, row_bytes, lmins);
@ -2531,14 +2687,14 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Avg filter */ /* Avg filter */
if (filter_to_do == PNG_FILTER_AVG) if (filter_to_do == PNG_FILTER_AVG)
{ {
(void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins); png_setup_avg_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row; best_row = png_ptr->try_row;
} }
else if ((filter_to_do & PNG_FILTER_AVG) != 0) else if ((filter_to_do & PNG_FILTER_AVG) != 0)
{ {
png_size_t sum; size_t sum;
png_size_t lmins = mins; size_t lmins = mins;
sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
@ -2555,16 +2711,16 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
} }
/* Paeth filter */ /* Paeth filter */
if ((filter_to_do == PNG_FILTER_PAETH) != 0) if (filter_to_do == PNG_FILTER_PAETH)
{ {
(void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins); png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row; best_row = png_ptr->try_row;
} }
else if ((filter_to_do & PNG_FILTER_PAETH) != 0) else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
{ {
png_size_t sum; size_t sum;
png_size_t lmins = mins; size_t lmins = mins;
sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
@ -2589,7 +2745,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Do the actual writing of a previously filtered row. */ /* Do the actual writing of a previously filtered row. */
static void static void
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t full_row_length/*includes filter byte*/) size_t full_row_length/*includes filter byte*/)
{ {
png_debug(1, "in png_write_filtered_row"); png_debug(1, "in png_write_filtered_row");

@ -48,7 +48,7 @@ bool flyCircleAnimator(void)
{ {
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
result = takeScreenshotAndCompareAgainstReference(driver, "-flyCircleAnimator.png", 100); result = takeScreenshotAndCompareAgainstReference(driver, "-flyCircleAnimator.png");
} }
device->closeDevice(); device->closeDevice();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show More