Commit 99fd5bcc authored by hybrid's avatar hybrid

Merged 1.4 branch, revisions 1106:1132.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1133 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 0dffdd46
...@@ -32,7 +32,7 @@ LDFLAGS = $(USERLDFLAGS) ...@@ -32,7 +32,7 @@ LDFLAGS = $(USERLDFLAGS)
all: all_linux all: all_linux
# target specific settings # target specific settings
all_linux all_win32 static_win32: LDFLAGS = -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht all_linux all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht
all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11 all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lXxf86vm -lXext -lX11
all_linux clean_linux: SYSTEM=Linux all_linux clean_linux: SYSTEM=Linux
all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc
......
...@@ -73,10 +73,10 @@ int main() ...@@ -73,10 +73,10 @@ int main()
is a class which can fetch the triangles from scene nodes for doing different is a class which can fetch the triangles from scene nodes for doing different
things with them, for example collision detection. There are different triangle things with them, for example collision detection. There are different triangle
selectors, and all can be created with the ISceneManager. In this example, selectors, and all can be created with the ISceneManager. In this example,
we create an OctTreeTriangleSelector, which optimizes the triangle output a l we create an OctTreeTriangleSelector, which optimizes the triangle output a
little bit by reducing it like an octree. This is very useful for huge meshes little bit by reducing it like an octree. This is very useful for huge meshes
like quake 3 levels. like quake 3 levels.
Afte we created the triangle selector, we attach it to the q3node. This is not After we created the triangle selector, we attach it to the q3node. This is not
necessary, but in this way, we do not need to care for the selector, for example necessary, but in this way, we do not need to care for the selector, for example
dropping it after we do not need it anymore. dropping it after we do not need it anymore.
*/ */
......
...@@ -185,7 +185,8 @@ int main() ...@@ -185,7 +185,8 @@ int main()
smgr->drawAll(); smgr->drawAll();
// set back old render target // set back old render target
driver->setRenderTarget(0); // The buffer might have been distorted, so clear it
driver->setRenderTarget(0, true, true, 0);
// make the cube visible and set the user controlled camera as active one // make the cube visible and set the user controlled camera as active one
test->setVisible(true); test->setVisible(true);
......
...@@ -78,7 +78,7 @@ CMainMenu::CMainMenu() ...@@ -78,7 +78,7 @@ CMainMenu::CMainMenu()
bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
bool& outAdditive, bool &outVSync, video::E_DRIVER_TYPE& outDriver) bool& outAdditive, bool &outVSync, video::E_DRIVER_TYPE& outDriver)
{ {
device = createDevice( video::EDT_BURNINGSVIDEO, device = createDevice( outDriver, //Varmint: 2007/12/18 video::EDT_BURNINGSVIDEO,
core::dimension2d<s32>(512, 384), 16, false, false, false, this); core::dimension2d<s32>(512, 384), 16, false, false, false, this);
device->getFileSystem()->addZipFileArchive("irrlicht.dat"); device->getFileSystem()->addZipFileArchive("irrlicht.dat");
......
...@@ -966,7 +966,7 @@ void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& ...@@ -966,7 +966,7 @@ void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc&
mb->drop(); mb->drop();
Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast(); Mesh->MeshBuffers[mbPos] = Mesh->MeshBuffers.getLast();
Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp; Mesh->MeshBuffers[Mesh->MeshBuffers.size()-1] = tmp;
mb->getMaterial() = *mat; mb->getMaterial() = tmp->getMaterial();
vtxCount=0; vtxCount=0;
} }
......
...@@ -214,11 +214,11 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -214,11 +214,11 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
} }
for (u32 j=0; j<filepath.size()-1; ++j) for (u32 j=0; j<filepath.size()-1; ++j)
path = path + filepath[j] + String("\\"); path = path + filepath[j] + String("/");
} }
else else
path = path + path = path +
String( SceneMgr->getParameters()->getAttributeAsString(DMF_TEXTURE_PATH)) + String("\\"); String( SceneMgr->getParameters()->getAttributeAsString(DMF_TEXTURE_PATH)) + String("/");
//texture and lightmap //texture and lightmap
ITexture *tex = 0; ITexture *tex = 0;
......
...@@ -11,6 +11,51 @@ ...@@ -11,6 +11,51 @@
#include "COpenGLDriver.h" #include "COpenGLDriver.h"
#include "IMaterialRenderer.h" #include "IMaterialRenderer.h"
//Varmint: 2007/12/18
#ifdef MACOSX
#define GL_COMBINE_EXT 0x8570
#define GL_COMBINE_RGB_EXT 0x8571
#define GL_COMBINE_ALPHA_EXT 0x8572
#define GL_RGB_SCALE_EXT 0x8573
#define GL_ADD_SIGNED_EXT 0x8574
#define GL_INTERPOLATE_EXT 0x8575
#define GL_CONSTANT_EXT 0x8576
#define GL_PRIMARY_COLOR_EXT 0x8577
#define GL_PREVIOUS_EXT 0x8578
#define GL_SOURCE0_RGB_EXT 0x8580
#define GL_SOURCE1_RGB_EXT 0x8581
#define GL_SOURCE2_RGB_EXT 0x8582
#define GL_SOURCE3_RGB_EXT 0x8583
#define GL_SOURCE4_RGB_EXT 0x8584
#define GL_SOURCE5_RGB_EXT 0x8585
#define GL_SOURCE6_RGB_EXT 0x8586
#define GL_SOURCE7_RGB_EXT 0x8587
#define GL_SOURCE0_ALPHA_EXT 0x8588
#define GL_SOURCE1_ALPHA_EXT 0x8589
#define GL_SOURCE2_ALPHA_EXT 0x858A
#define GL_SOURCE3_ALPHA_EXT 0x858B
#define GL_SOURCE4_ALPHA_EXT 0x858C
#define GL_SOURCE5_ALPHA_EXT 0x858D
#define GL_SOURCE6_ALPHA_EXT 0x858E
#define GL_SOURCE7_ALPHA_EXT 0x858F
#define GL_OPERAND0_RGB_EXT 0x8590
#define GL_OPERAND1_RGB_EXT 0x8591
#define GL_OPERAND2_RGB_EXT 0x8592
#define GL_OPERAND3_RGB_EXT 0x8593
#define GL_OPERAND4_RGB_EXT 0x8594
#define GL_OPERAND5_RGB_EXT 0x8595
#define GL_OPERAND6_RGB_EXT 0x8596
#define GL_OPERAND7_RGB_EXT 0x8597
#define GL_OPERAND0_ALPHA_EXT 0x8598
#define GL_OPERAND1_ALPHA_EXT 0x8599
#define GL_OPERAND2_ALPHA_EXT 0x859A
#define GL_OPERAND3_ALPHA_EXT 0x859B
#define GL_OPERAND4_ALPHA_EXT 0x859C
#define GL_OPERAND5_ALPHA_EXT 0x859D
#define GL_OPERAND6_ALPHA_EXT 0x859E
#define GL_OPERAND7_ALPHA_EXT 0x859F
#endif
namespace irr namespace irr
{ {
namespace video namespace video
......
...@@ -703,6 +703,13 @@ ITerrainSceneNode* CSceneManager::addTerrainSceneNode( ...@@ -703,6 +703,13 @@ ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
{ {
io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName); io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName);
if(!file && !addAlsoIfHeightmapEmpty)
{
os::Printer::log("Could not load terrain, because file could not be opened.",
heightMapFileName, ELL_ERROR);
return 0;
}
ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id, ITerrainSceneNode* terrain = addTerrainSceneNode(file, parent, id,
position, rotation, scale, vertexColor, maxLOD, patchSize, position, rotation, scale, vertexColor, maxLOD, patchSize,
smoothFactor, addAlsoIfHeightmapEmpty); smoothFactor, addAlsoIfHeightmapEmpty);
...@@ -730,8 +737,7 @@ ITerrainSceneNode* CSceneManager::addTerrainSceneNode( ...@@ -730,8 +737,7 @@ ITerrainSceneNode* CSceneManager::addTerrainSceneNode(
if (!heightMapFile && !addAlsoIfHeightmapEmpty) if (!heightMapFile && !addAlsoIfHeightmapEmpty)
{ {
os::Printer::log("Could not load terrain, because file could not be opened.", os::Printer::log("Could not load terrain, because file could not be opened.", ELL_ERROR);
heightMapFile->getFileName(), ELL_ERROR);
return 0; return 0;
} }
......
...@@ -54,11 +54,9 @@ namespace scene ...@@ -54,11 +54,9 @@ namespace scene
//! destructor //! destructor
CTerrainSceneNode::~CTerrainSceneNode ( ) CTerrainSceneNode::~CTerrainSceneNode ( )
{ {
if (TerrainData.LODDistanceThreshold) delete [] TerrainData.LODDistanceThreshold;
delete [] TerrainData.LODDistanceThreshold;
if (TerrainData.Patches) delete [] TerrainData.Patches;
delete [] TerrainData.Patches;
if (FileSystem) if (FileSystem)
FileSystem->drop(); FileSystem->drop();
...@@ -525,67 +523,6 @@ namespace scene ...@@ -525,67 +523,6 @@ namespace scene
} }
} }
void CTerrainSceneNode::preRenderLODCalculations_old()
{
SceneManager->registerNodeForRendering( this );
// Do Not call ISceneNode::OnRegisterSceneNode ( ), this node should have no children
// Determine the camera rotation, based on the camera direction.
core::line3d<f32> line;
line.start = SceneManager->getActiveCamera()->getAbsolutePosition();
line.end = SceneManager->getActiveCamera()->getTarget();
core::vector3df cameraRotation = line.getVector().getHorizontalAngle();
core::vector3df cameraPosition = SceneManager->getActiveCamera()->getPosition ( );
// Only check on the Camera's Y Rotation
if (( fabs(cameraRotation.X - OldCameraRotation.X) < CameraRotationDelta) &&
( fabs(cameraRotation.Y - OldCameraRotation.Y) < CameraRotationDelta))
{
if ((fabs(cameraPosition.X - OldCameraPosition.X) < CameraMovementDelta) &&
(fabs(cameraPosition.Y - OldCameraPosition.Y) < CameraMovementDelta) &&
(fabs(cameraPosition.Z - OldCameraPosition.Z) < CameraMovementDelta))
{
return;
}
}
OldCameraPosition = cameraPosition;
OldCameraRotation = cameraRotation;
const SViewFrustum* frustum = SceneManager->getActiveCamera()->getViewFrustum();
// Determine each patches LOD based on distance from camera ( and whether or not they are in
// the view frustum ).
for( s32 j = 0; j < TerrainData.PatchCount * TerrainData.PatchCount; ++j )
{
if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) )
{
f32 distance = (cameraPosition.X - TerrainData.Patches[j].Center.X) * (cameraPosition.X - TerrainData.Patches[j].Center.X) +
(cameraPosition.Y - TerrainData.Patches[j].Center.Y) * (cameraPosition.Y - TerrainData.Patches[j].Center.Y) +
(cameraPosition.Z - TerrainData.Patches[j].Center.Z) * (cameraPosition.Z - TerrainData.Patches[j].Center.Z);
for( s32 i = TerrainData.MaxLOD - 1; i >= 0; --i )
{
if( distance >= TerrainData.LODDistanceThreshold[i] )
{
TerrainData.Patches[j].CurrentLOD = i;
break;
}
//else if( i == 0 )
{
// If we've turned off a patch from viewing, because of the frustum, and now we turn around and it's
// too close, we need to turn it back on, at the highest LOD. The if above doesn't catch this.
TerrainData.Patches[j].CurrentLOD = 0;
}
}
}
else
{
TerrainData.Patches[j].CurrentLOD = -1;
}
}
}
void CTerrainSceneNode::preRenderIndicesCalculations() void CTerrainSceneNode::preRenderIndicesCalculations()
{ {
IndicesToRender = 0; IndicesToRender = 0;
...@@ -935,8 +872,8 @@ namespace scene ...@@ -935,8 +872,8 @@ namespace scene
} }
//! used to get the indices when generating index data for patches at varying levels of detail. //! used to get the indices when generating index data for patches at varying levels of detail.
u32 CTerrainSceneNode::getIndex(const s32& PatchX, const s32& PatchZ, u32 CTerrainSceneNode::getIndex(const s32 PatchX, const s32 PatchZ,
const s32& PatchIndex, u32 vX, u32 vZ) const const s32 PatchIndex, u32 vX, u32 vZ) const
{ {
// top border // top border
if (vZ == 0) if (vZ == 0)
...@@ -945,7 +882,7 @@ namespace scene ...@@ -945,7 +882,7 @@ namespace scene
TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Top->CurrentLOD && TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Top->CurrentLOD &&
(vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD)) != 0 ) (vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD)) != 0 )
{ {
vX = vX - vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD ); vX -= vX % ( 1 << TerrainData.Patches[PatchIndex].Top->CurrentLOD );
} }
} }
else else
...@@ -955,7 +892,7 @@ namespace scene ...@@ -955,7 +892,7 @@ namespace scene
TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Bottom->CurrentLOD && TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Bottom->CurrentLOD &&
(vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD)) != 0) (vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD)) != 0)
{ {
vX = vX - vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD ); vX -= vX % ( 1 << TerrainData.Patches[PatchIndex].Bottom->CurrentLOD );
} }
} }
...@@ -966,7 +903,7 @@ namespace scene ...@@ -966,7 +903,7 @@ namespace scene
TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Left->CurrentLOD && TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Left->CurrentLOD &&
( vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD ) ) != 0) ( vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD ) ) != 0)
{ {
vZ = vZ - vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD ); vZ -= vZ % ( 1 << TerrainData.Patches[PatchIndex].Left->CurrentLOD );
} }
} }
else else
...@@ -976,7 +913,7 @@ namespace scene ...@@ -976,7 +913,7 @@ namespace scene
TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Right->CurrentLOD && TerrainData.Patches[PatchIndex].CurrentLOD < TerrainData.Patches[PatchIndex].Right->CurrentLOD &&
( vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD ) ) != 0) ( vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD ) ) != 0)
{ {
vZ = vZ - vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD ); vZ -= vZ % ( 1 << TerrainData.Patches[PatchIndex].Right->CurrentLOD );
} }
} }
...@@ -1175,12 +1112,6 @@ namespace scene ...@@ -1175,12 +1112,6 @@ namespace scene
TerrainData.Patches[index].Right = &TerrainData.Patches[x * TerrainData.PatchCount + z + 1]; TerrainData.Patches[index].Right = &TerrainData.Patches[x * TerrainData.PatchCount + z + 1];
else else
TerrainData.Patches[index].Right = 0; TerrainData.Patches[index].Right = 0;
if ( TerrainData.Patches[index].DebugText )
{
TerrainData.Patches[index].DebugText->setPosition ( TerrainData.Patches[index].Center );
}
} }
} }
...@@ -1225,7 +1156,7 @@ namespace scene ...@@ -1225,7 +1156,7 @@ namespace scene
TerrainData.Patches[i].CurrentLOD = lod; TerrainData.Patches[i].CurrentLOD = lod;
} }
void CTerrainSceneNode::setCurrentLODOfPatches(core::array<s32>& lodarray) void CTerrainSceneNode::setCurrentLODOfPatches(const core::array<s32>& lodarray)
{ {
for (s32 i=0; i<TerrainData.PatchCount * TerrainData.PatchCount; ++i) for (s32 i=0; i<TerrainData.PatchCount * TerrainData.PatchCount; ++i)
TerrainData.Patches[i].CurrentLOD = lodarray[i]; TerrainData.Patches[i].CurrentLOD = lodarray[i];
......
...@@ -102,8 +102,7 @@ namespace scene ...@@ -102,8 +102,7 @@ namespace scene
//! \param rotation: New rotation of the node in degrees. //! \param rotation: New rotation of the node in degrees.
virtual void setRotation(const core::vector3df& rotation); virtual void setRotation(const core::vector3df& rotation);
//! Sets the pivot point for rotation of this node. This is useful for the TiledTerrainManager to //! Sets the pivot point for rotation of this node.
//! rotate all terrain tiles around a global world point.
//! NOTE: The default for the RotationPivot will be the center of the individual tile. //! NOTE: The default for the RotationPivot will be the center of the individual tile.
virtual void setRotationPivot( const core::vector3df& pivot ); virtual void setRotationPivot( const core::vector3df& pivot );
...@@ -152,7 +151,7 @@ namespace scene ...@@ -152,7 +151,7 @@ namespace scene
//! \param LOD: The level of detail to get for that patch. If -1, then get //! \param LOD: The level of detail to get for that patch. If -1, then get
//! the CurrentLOD. If the CurrentLOD is set to -1, meaning it's not shown, //! the CurrentLOD. If the CurrentLOD is set to -1, meaning it's not shown,
//! then it will retrieve the triangles at the highest LOD ( 0 ). //! then it will retrieve the triangles at the highest LOD ( 0 ).
//! \return: Number if indices put into the buffer. //! \return: Number of indices put into the buffer.
virtual s32 getIndicesForPatch(core::array<u32>& indices, virtual s32 getIndicesForPatch(core::array<u32>& indices,
s32 patchX, s32 patchZ, s32 LOD = 0 ); s32 patchX, s32 patchZ, s32 LOD = 0 );
...@@ -198,8 +197,8 @@ namespace scene ...@@ -198,8 +197,8 @@ namespace scene
//virtual void setDynamicSelectorUpdate ( bool bVal ) { DynamicSelectorUpdate = bVal; } //virtual void setDynamicSelectorUpdate ( bool bVal ) { DynamicSelectorUpdate = bVal; }
//! Override the default generation of distance thresholds for determining the LOD a patch //! Override the default generation of distance thresholds for determining the LOD a patch
//! is rendered at. If any LOD is overridden, then the scene node will no longer apply //! is rendered at. If any LOD is overridden, then the scene node will no longer apply
//! scaling factors to these values. If you override these distances, and then apply //! scaling factors to these values. If you override these distances, and then apply
//! a scale to the scene node, it is your responsibility to update the new distances to //! a scale to the scene node, it is your responsibility to update the new distances to
//! work best with your new terrain size. //! work best with your new terrain size.
virtual bool overrideLODDistance( s32 LOD, f64 newDistance ); virtual bool overrideLODDistance( s32 LOD, f64 newDistance );
...@@ -225,20 +224,17 @@ namespace scene ...@@ -225,20 +224,17 @@ namespace scene
private: private:
friend class CTerrainTriangleSelector; friend class CTerrainTriangleSelector;
friend class CTiledTerrainSceneNodeManager;
struct SPatch struct SPatch
{ {
SPatch() SPatch()
: CurrentLOD(-1), DebugText(0), : CurrentLOD(-1), Top(0), Bottom(0), Right(0), Left(0)
Top(0), Bottom(0), Right(0), Left(0)
{ {
} }
s32 CurrentLOD; s32 CurrentLOD;
core::aabbox3df BoundingBox; core::aabbox3df BoundingBox;
core::vector3df Center; core::vector3df Center;
scene::ITextSceneNode* DebugText;
SPatch* Top; SPatch* Top;
SPatch* Bottom; SPatch* Bottom;
SPatch* Right; SPatch* Right;
...@@ -280,11 +276,10 @@ namespace scene ...@@ -280,11 +276,10 @@ namespace scene
}; };
virtual void preRenderLODCalculations(); virtual void preRenderLODCalculations();
virtual void preRenderLODCalculations_old();
virtual void preRenderIndicesCalculations(); virtual void preRenderIndicesCalculations();
//! get indices when generating index data for patches at varying levels of detail. //! get indices when generating index data for patches at varying levels of detail.
u32 getIndex(const s32& PatchX, const s32& PatchZ, const s32& PatchIndex, u32 vX, u32 vZ) const; u32 getIndex(const s32 PatchX, const s32 PatchZ, const s32 PatchIndex, u32 vX, u32 vZ) const;
//! calculate smooth normals //! calculate smooth normals
void calculateNormals(SMeshBufferLightMap* pMeshBuffer ); void calculateNormals(SMeshBufferLightMap* pMeshBuffer );
...@@ -302,7 +297,7 @@ namespace scene ...@@ -302,7 +297,7 @@ namespace scene
void setCurrentLODOfPatches(s32 i); void setCurrentLODOfPatches(s32 i);
//! sets the CurrentLOD of TerrainData patches to the LODs specified in the array //! sets the CurrentLOD of TerrainData patches to the LODs specified in the array
void setCurrentLODOfPatches(core::array<s32>& lodarray); void setCurrentLODOfPatches(const core::array<s32>& lodarray);
//! Apply transformation changes( scale, position, rotation ) //! Apply transformation changes( scale, position, rotation )
void applyTransformation(); void applyTransformation();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* pngerror.c - stub functions for i/o and memory allocation
*
* Last changed in libpng 1.2.13 November 13, 2006
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2006 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This file provides a location for all error handling. Users who
* need special error handling are expected to write replacement functions
* and use png_set_error_fn() to use those functions. See the instructions
* at each function.
*/
#define PNG_INTERNAL
#include "png.h"
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
static void /* PRIVATE */
png_default_error PNGARG((png_structp png_ptr,
png_const_charp error_message));
static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr,
png_const_charp warning_message));
/* This function is called whenever there is a fatal error. This function
* should not be changed. If there is a need to handle errors differently,
* you should supply a replacement error function and use png_set_error_fn()
* to replace the error function at run-time.
*/
void PNGAPI
png_error(png_structp png_ptr, png_const_charp error_message)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{
if (*error_message == '#')
{
int offset;
for (offset=1; offset<15; offset++)
if (*(error_message+offset) == ' ')
break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
int i;
for (i=0; i<offset-1; i++)
msg[i]=error_message[i+1];
msg[i]='\0';
error_message=msg;
}
else
error_message+=offset;
}
else
{
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
msg[0]='0';
msg[1]='\0';
error_message=msg;
}
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message);
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, error_message);
}
/* This function is called whenever there is a non-fatal error. This function
* should not be changed. If there is a need to handle warnings differently,
* you should supply a replacement warning function and use
* png_set_error_fn() to replace the warning function at run-time.
*/
void PNGAPI
png_warning(png_structp png_ptr, png_const_charp warning_message)
{
int offset = 0;
if (png_ptr != NULL)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (png_ptr->flags&
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
#endif
{
if (*warning_message == '#')
{
for (offset=1; offset<15; offset++)
if (*(warning_message+offset) == ' ')
break;
}
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
}
else
png_default_warning(png_ptr, warning_message+offset);
}
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
error_message)
{
int iout = 0, iin = 0;
while (iin < 4)
{
int c = png_ptr->chunk_name[iin++];
if (isnonalpha(c))
{
buffer[iout++] = '[';
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
buffer[iout++] = png_digit[c & 0x0f];
buffer[iout++] = ']';
}
else
{
buffer[iout++] = (png_byte)c;
}
}
if (error_message == NULL)
buffer[iout] = 0;
else
{
buffer[iout++] = ':';
buffer[iout++] = ' ';
png_strncpy(buffer+iout, error_message, 63);
buffer[iout+63] = 0;
}
}
void PNGAPI
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
{
char msg[18+64];
if (png_ptr == NULL)
png_error(png_ptr, error_message);
else
{
png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg);
}
}
void PNGAPI
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
{
char msg[18+64];
if (png_ptr == NULL)
png_warning(png_ptr, warning_message);
else
{
png_format_buffer(png_ptr, msg, warning_message);
png_warning(png_ptr, msg);
}
}
/* This is the default error handling function. Note that replacements for
* this function MUST NOT RETURN, or the program will likely crash. This
* function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn().
*/
static void /* PRIVATE */
png_default_error(png_structp png_ptr, png_const_charp error_message)
{
#ifndef PNG_NO_CONSOLE_IO
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*error_message == '#')
{
int offset;
char error_number[16];
for (offset=0; offset<15; offset++)
{
error_number[offset] = *(error_message+offset+1);
if (*(error_message+offset) == ' ')
break;
}
if((offset > 1) && (offset < 15))
{
error_number[offset-1]='\0';
fprintf(stderr, "libpng error no. %s: %s\n", error_number,
error_message+offset);
}
else
fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
}
else
#endif
fprintf(stderr, "libpng error: %s\n", error_message);
#endif
#ifdef PNG_SETJMP_SUPPORTED
if (png_ptr)
{
# ifdef USE_FAR_KEYWORD
{
jmp_buf jmpbuf;
png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf));
longjmp(jmpbuf, 1);
}
# else
longjmp(png_ptr->jmpbuf, 1);
# endif
}
#else
PNG_ABORT();
#endif
#ifdef PNG_NO_CONSOLE_IO
/* make compiler happy */ ;
if (&error_message != NULL)
return;
#endif
}
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
* here if you don't want them to. In the default configuration, png_ptr is
* not used, but it is passed in case it may be useful.
*/
static void /* PRIVATE */
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
{
#ifndef PNG_NO_CONSOLE_IO
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*warning_message == '#')
{
int offset;
char warning_number[16];
for (offset=0; offset<15; offset++)
{
warning_number[offset]=*(warning_message+offset+1);
if (*(warning_message+offset) == ' ')
break;
}
if((offset > 1) && (offset < 15))
{
warning_number[offset-1]='\0';
fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
warning_message+offset);
}
else
fprintf(stderr, "libpng warning: %s\n", warning_message);
}
else
# endif
fprintf(stderr, "libpng warning: %s\n", warning_message);
#else
/* make compiler happy */ ;
if (warning_message)
return;
#endif
/* make compiler happy */ ;
if (png_ptr)
return;
}
/* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
*/
void PNGAPI
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warning_fn)
{
if (png_ptr == NULL)
return;
png_ptr->error_ptr = error_ptr;
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
}
/* This function returns a pointer to the error_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_error_ptr(png_structp png_ptr)
{
if (png_ptr == NULL)
return NULL;
return ((png_voidp)png_ptr->error_ptr);
}
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
void PNGAPI
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
{
if(png_ptr != NULL)
{
png_ptr->flags &=
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
}
}
#endif
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* pngrio.c - functions for data input
*
* Last changed in libpng 1.2.13 November 13, 2006
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2006 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This file provides a location for all input. Users who need
* special handling are expected to write a function that has the same
* arguments as this and performs a similar function, but that possibly
* has a different input method. Note that you shouldn't change this
* function, but rather write a replacement function and then make
* libpng use it at run time with png_set_read_fn(...).
*/
#define PNG_INTERNAL
#include "png.h"
#if defined(PNG_READ_SUPPORTED)
/* Read the data from whatever input you are using. The default routine
reads from a file pointer. Note that this routine sometimes gets called
with very small lengths, so you should implement some kind of simple
buffering if you are using unbuffered reads. This should never be asked
to read more then 64K on a 16 bit machine. */
void /* PRIVATE */
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4,"reading %d bytes\n", (int)length);
if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL read function");
}
#if !defined(PNG_NO_STDIO)
/* This is the function that does the actual reading of data. If you are
not reading from a standard C stream, you should create a replacement
read_data function and use it at run time with png_set_read_fn(), rather
than changing the library. */
#ifndef USE_FAR_KEYWORD
void PNGAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
if(png_ptr == NULL) return;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
check = 0;
#else
check = (png_size_t)fread(data, (png_size_t)1, length,
(png_FILE_p)png_ptr->io_ptr);
#endif
if (check != length)
png_error(png_ptr, "Read Error");
}
#else
/* this is the model-independent version. Since the standard I/O library
can't handle far buffers in the medium and small models, we have to copy
the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
static void PNGAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
int check;
png_byte *n_data;
png_FILE_p io_ptr;
if(png_ptr == NULL) return;
/* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
{
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
check = 0;
#else
check = fread(n_data, 1, length, io_ptr);
#endif
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err;
check = 0;
remaining = length;
do
{
read = MIN(NEAR_BUF_SIZE, remaining);
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
err = 0;
#else
err = fread(buf, (png_size_t)1, read, io_ptr);
#endif
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if(err != read)
break;
else
check += err;
data += read;
remaining -= read;
}
while (remaining != 0);
}
if ((png_uint_32)check != (png_uint_32)length)
png_error(png_ptr, "read Error");
}
#endif
#endif
/* This function allows the application to supply a new input function
for libpng if standard C streams aren't being used.
This function takes as its arguments:
png_ptr - pointer to a png input data structure
io_ptr - pointer to user supplied structure containing info about
the input functions. May be NULL.
read_data_fn - pointer to a new input function that takes as its
arguments a pointer to a png_struct, a pointer to
a location where input data can be stored, and a 32-bit
unsigned int that is the number of bytes to be read.
To exit and output any fatal error messages the new write
function should call png_error(png_ptr, "Error msg"). */
void PNGAPI
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
{
if(png_ptr == NULL) return;
png_ptr->io_ptr = io_ptr;
#if !defined(PNG_NO_STDIO)
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;
#else
png_ptr->read_data_fn = read_data_fn;
#endif
/* It is an error to write to a read device */
if (png_ptr->write_data_fn != NULL)
{
png_ptr->write_data_fn = NULL;
png_warning(png_ptr,
"It's an error to set both read_data_fn and write_data_fn in the ");
png_warning(png_ptr,
"same structure. Resetting write_data_fn to NULL.");
}
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
png_ptr->output_flush_fn = NULL;
#endif
}
#endif /* PNG_READ_SUPPORTED */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment